I am making a web API/Rest API in MVC where each API takes one parameter called user_session
So when a user logs in, I generate a 10 digit session and pass it back to user which needs to be given as input for any subsequent API calls.
Here's what my typical code looks like:
$.ajax({
url: '#Url.Action("GetUserDetail", "myapi")',
type: "GET",
data: { UserID: '#user.user_id', SessionID: '#user_session' },
dataType: "json",
success: function (response) {
}
})
My question is, is this the right approach or is there a better way of doing it? Is it secure?
You can very well use the HTTP Cookies for remembering the session instead of manually passing it as a param for every request.
I’ll give very short explanation on this topic.
Server sets a cookie when a user logs-in.
This cookie will be sent to all the api calls as it is defined as a HTTP cookie.
Server can validate or know about the session using this cookie value in header of the request.
Related
In Below example, if i use username and password, then anyone can see it in page source. Is there any solution to hide the username and password or can we put credentials in json or xml file and access it to set it in header, if yes please let us know the solution.
$.ajax({ type: "POST",
contentType: false,
data: formData,
url: "external domain URL",
crossDomain: true,
cache: false,
processData: false,
beforeSend: function(xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa("username" + ":" + "Password"));
xhr.withCredentials = true;
},
You can encode username and password into a text and use that text, but this is dangerous and unfeasible, because that way if someone manages to decode it for some reason, then it will be a huge security leak. And if the server accepts an encoded text, that would also be a security leak, so you should avoid this kind of approach, unless you use some temporary tokens, but that would only reduce, but not eliminate the risk.
Instead, it would be much better if you had a page, which would work as follows:
when the data is needed, a request is sent to the server to gather the username and password
the server will respond with an encoded variation of these data
the client-side would decode this
the client-side will send the request
Also, you could use your server as a proxy, that is, send all the requests to your own server instead of the target server and the server on its turn will forward the request to the target server and the response to the client-side. This would be even better.
I'm trying to access my API using AJAX with the simple following code:
$.ajax({
type: "GET",
url: "http://SERVER_IP/API-test/public/login/username/userpass",
crossDomain: 'true',
dataType: 'jsonp',
contentType: "application/json",
success: function(whatever){
alert('HTTP request is a success');
console.log(whatever);
},
error: function(errorText){
console.log("Error Test: ",errorText);
}
});
and in response I get 400 (Bad request) from the server. This code generates following request:
http://SERVER_IP/API-test/public/login/username/userpass?callback=jQuery1112009842987591400743_1429090394748&_=1429090394749
I guess that the problem is in the part this part:
?callback=jQuery1112009842987591400743_1429090394748&_=1429090394749
that is added to my request.
How could I avoid this? Or could be the root of the problem somewhere else?
Whether the Query Parameters result in a HTTP Code 400 depends on you server implementation.
Bot parameters are added by jQuery.ajax to avoid issues with caching.
The _ parameter includes the current timestamp to avoid caching.
The callback parameter is added because you are querying a "remote" server (= crossdomain) with jsonp "technique", which means the url is not same as the url the javascript/html/etc files have been loaded from.
Beside that you are querying a login endpoint (at least it is named like that) and do not send any verification data like username or password. When performing a GET request, these information needs to be included in the query part. Maybe the server returns "Bad Request", because the credentials are missing?
Let's consider a trivial use case: User edits his profile + we have a RESTful server. This means we have to
send a token to the server and at the same time the new information about the editing. First, the server has to decode the token, and later to CRUD the DB. We want also to send back to the client a new json model about the new user profile.
BUT the token is really a huge one, so we must send it with a POST request. We can send the additional information as a query string at the same HTTP Post. Ember Data doesn't give us the ability to decide on sending a POST request. So we have to write a manual Ember.$.ajax. But how would we retrieve the new user model to Ember? We want to take advantage of Ember Data ORM's relationships and not reinventing the wheel.
Just for the record, the manual valid post request on the EditController is (after enabling CORS on the server)+(fBSignedRequest=> the token in my case):
Ember.$.ajax('http://myapi.com/api/usrEdit?Name='+myNewName, {
type: 'POST',
dataType: "json",
data: {fBSignedRequest: this.get("FBSignedRequest")},
success: function(data, response) {
console.log(data, response);
App.newUserProfile = data; //want it to become a part of the ED ORM
},
error: function (xhr) {
console.log('error')
}
});
This is really a trivial task to ask. Why couldn't I found any answer for over a month for this? How would you do the combination of a manual ajax and a build in Ember Data ORM?
If you have another idea about this whole authentication, I will be glad to hear.
Thank you a lot!
You could simply push the model you retrieve via your request into the store. See http://emberjs.com/guides/models/pushing-records-into-the-store/
I apologize in advance if this question sounds naive to you.
The problem is this: I have this function and I want the callback function to send the "response" back to my server via Ajax.
function FbInviteFriends()
{
FB.ui({
method: 'apprequests',
message: 'Hi! Join me on XXXXXXX'
},
//My callback function
function(response){
//Send response to my server
}
Is there a way to check that the response I'm going to receive server-side is actually the same I got when the callback function is called and that the response hasn't been modified on the client-side by the user?
Thanks!
There's a few ways, but all of them fall on the same principle - you can never know for sure, so treat it with a grain of salt and validate.
That said, one way to put at least one usage constraint may look like this:
Page accessed: Generate a token GUID. Render it at the client.
Store in the user session the moment it was created/used, together with user profile.
Client appends the token to all Ajax posts.
Token is validated at the server; must match SessionID, user profile (if any), and maximum usage timeout.
If it fails validation, abort the operation.
I have a form and post it to server using json data,and the server save it in database. here is my code
function saveChanges() {
var items = [];
$('ol.item_list > li.item').each(function(){
items.push(getItemData($(this)));
});
var csrftoken = $.cookie('csrftoken');
$.ajax({
url : '',
type: 'POST',
headers : {"X-CSRFToken": csrftoken},
data : $.toJSON(items),
success: function(data, textStatus, jqXHR){
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown){
alert(textStatus);
},
});
}
The problem is, I call saveChanges (via a button) twice, all return 200 http ok. So I got duplicate data in database. Should the csrf token provent duplicate sumbit? How can I fix it?
You should prevent double submission by taking care to properly
lay out your script execution flow & script structure so that you prevent that.
No, the CSRF token doesn't prevent duplicate submit of any kind. Its purpose is to prevent Cross Site Request Forgery, nothing else. It creates a token so nobody can trick you in submitting requests you don't intend to do.
If you want to prevent duplicate submits, a way would be to disable the submit button after it is clicked once. However, this is by no means a good solution, since JavaScript runs on client side and can easily be manipulated (e.g. via Firebug). So duplicate submits would still be possible, just not that obviously.
A better way is to do validation in your server-side Python code. You can check if the submitted data is already in the database and, if so, ignore the request or optionally return an error message. This makes sure that even by fiddling around with the JavaScript, an evil-meaning user cannot save data twice.
I would use both of these means, the first one simply to tell the user that he should not try to submit the same data twice - that's just an interface perk.