login flow with AngularJS and JWT - angularjs

In my webapp, when the main page is requested by a non logged in user, I display a login page (containing only a login form). Then the user inputs its userid and pwd and an AngularJS controller issues a HTTP POST request to /connection which returns a JWT autentification token in case of accepted credentials.
Then I'd like the AngularJS controller to issue a GET on / passing the token in the header so the next loaded page is the main webapp page which the connected user can start to play with.
How do I acheive that with AngularJS. Should I use $document.location.href ? If yes how can the token set into the HTTP header ?
Thanks

You can Do it in 2 ways:
1-Use Custom Header for all the initiated Requests (doesn't matter get, post, etc..) and in here our friends posted a lot of different Approaches.
AngularJS $http custom header for all requests
2-Overriding the Header for the Request like this:
$http.get(/*The Call URL*/'http://myawesomeurl/jsondata',/*Configuration Object*/
{/*Overriding the header of the request*/
headers: {
'Content-Type': 'application/json',//request content type
'Authorization': 'token d2VudHdvcnRobWFuOkNoYW5nZV9tZQ=='//Token parameter
//,'myAwesomeHeaderParam':'the header is all yours, add or remove anything'
}
})
.success(function (data, status, headers, config) {
console.log(data);//Received data
})
.error(function (data, status, headers, config) {
console.log('Error Status:'+status);
console.log(data);//Any Server Response values in the case of error
});
//Another Way for initiating the request just for your info
/* var reqInfo = {
method: 'GET',//POST, PUT
url: 'http://myawesomeurl/jsondata',
headers: {
'Content-Type': 'application/json',//request content type (can be not used)
'Authorization': 'token d2VudHdvcnRobWFuOkNoYW5nZV9tZQ=='//Token parameter
}
//,data:{'myAwesomeParameter':'in case of post or put, etc..'} //Request body
};
$http(reqInfo).success(....*/
And you can know more about the Configuration Object here

Related

Is Excel clearing our http request authorization header attribute?

We are trying to get our Office Excel add-in to contact one of our own Web API services so it can send and receive data from it. For the request to be authorised we must fill out the Authorization header attribute. This is how we are doing the request, which works perfectly well in all of our normal web applications.
this.LoginAuth = function (authString) {
$http.defaults.headers.common.Authorization = 'Basic ' + authString;
return $http({
url: MainFactory.GetWebAPILocation() + '/API/User/AddInLoginAuth',
dataType: 'json',
method: 'POST',
data: {},
headers: {
"Content-Type": "application/json"
}
});
}
However, when the request is made through the add-in the Authorization attribute has been cleared down causing our request to fail. Is this clearing of the attribute being done by Excel? And if so, is there a way in which we can stop it?
Turns out this was a CORS issue in our Web API service.

Login to Parse.com DB using API returns XMLHttpRequest header error

Here is the call I make the Parse.com's API to login the user:
var deferred = $q.defer();
$http({
method: "GET",
url: "https://api.parse.com/1/login",
headers: {
"X-Parse-Application-Id": PARSE_CREDENTIALS.APP_ID,
"X-Parse-REST-API-Key": PARSE_CREDENTIALS.REST_API_KEY,
"Content-Type": "application/json"
},
data: {
"username": credentials.username.toLowerCase(),
"password": credentials.password
}
}).success(function(data) {
deferred.resolve(data);
}).error(function() {
deferred.reject("error")
});
return deferred.promise;
When I trigger this Angular service method, I get the following error in my console:
XMLHttpRequest cannot load https://api.parse.com/1/login. Request header field Access-Control-Allow-Headers is not allowed by Access-Control-Allow-Headers.
I'm not sure how to resolve this. Here are the current contents of the common headers object for my Angular app:
Object {Accept: "application/json, text/plain, */*", Access-Control-Allow-Headers: "origin, content-type, accept"}
I implement the $http service almost exactly the same for my custom classes without error. The only difference is the URL. Can anyone provide an answer as to why I am getting this error?
EDIT: From this other question, I've gathered that the header field error is the result of the header in the Parse.com response, not in my request. But I am not sure how to proceed now.
EDIT 2: Attached is an image of the HTTP request and response headers that I get when I ping the login API URL.
Are you setting these headers for all http requests somewhere in your angular app?
I'm not sure how to resolve this. Here are the current contents of the
common headers object for my Angular app:
Object {Accept: "application/json, text/plain, */*", Access-Control-Allow-Headers: "origin,
These should come from the server only (response headers), so if they are being set somewhere in the request, then the server would error due to extra headers it was not expecting.
So here is the relevant part of the documentation from AngularJS about using the $http dependency.
params – {Object.<string|Object>} – Map of strings or objects which will be turned to ?key1=value1&key2=value2 after the url. If the value is not a string, it will be JSONified.
data – {string|Object} – Data to be sent as the request message data.
So I conflated params with data. Parse.com expects an URL-parameterized string of the username and password. My confusion was partly because I thought there was a mismatch of request and response headers. But this was not the case.
var deferred = $q.defer();
$http({
url: "https://api.parse.com/1/login",
headers: {
"X-Parse-Application-Id": PARSE_CREDENTIALS.APP_ID,
"X-Parse-REST-API-Key": PARSE_CREDENTIALS.REST_API_KEY,
"Content-Type": "application/json; charset=utf-8"
},
params: {
"username": credentials.username.toLowerCase(),
"password": credentials.password
}
}).success(function(data, status, headers, config) {
deferred.resolve(data);
}).error(function(data, status, headers, config) {
deferred.reject("error")
});
Additional note: For any Angular developers out there who are concerned about the security of user credentials, you will need to set up SSL for your site to ensure that this data does not fall victim to a man-in-the-middle attack. For information on how to set up SSL with Parse.com, read this article.
If, you do not want to pay for an SSL certificate as DigiCert prescribes (e.g. this app is not for customers, but for internal purposes), check out this article for information on how to create your own SSL certificate and save yourself +$100/year.

Not able to POST data to RESTFul service from AngularJS

Hope some one can help me here.
I am trying to POST a JOSN data to restful service. But am getting below error.
Error:
XMLHttpRequest cannot load http://localhost:8080/PortalService/rest/PutService/PutLogicalTeam. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.
This is how i am invoking the service
$http.post('http://localhost:8080/PortalService/rest/PutService/PutLogicalTeam', $scope.strLogiTeam
).success(function(data, status, headers, config) {
console.log("success");
}).error(function(data, status, headers, config) {
// Handle error
console.log(status);
});
My service.
I am not even trying to pull the data. I am just trying to check whether my service is getting invoked or not.
#POST
#Consumes("application/json")
#Path("/PutLogicalTeam")
public void putNewLogicalTeam(LogicalTeam newLogicalTeam)
{
System.out.println("Invoked");
}
I also tried like below
$http({
method: 'POST',
dataType: 'jsonp',
data: $scope.strLogiTeam,
url:'http://localhost:8080/PortalService/rest/PutService/PutLogicalTeam',
headers: {'Content-Type':'application/json'}
});
Can some one review and help. Also suggest the better way to use the web service

AngularJS - Cannot read response headers from $http

My http response contains the headers Authentication (as mentioned here: Authentication:76efbc0946773b62c93e952b502a47acd898200f6f80dc46ac87ffc501c00780) when I inspect the request with the inspector, but a call to headers("Authentication") returns null
return $http({
method: "GET",
url: url,
headers: {
'Content-Type': "application/json"
}
}).success(function (data, status, headers, config) {
console.log(headers("Authentication"));
})
Do you have any idea about what I could be doing the wrong way ?
FYI, i've tried to switch it back to a "promise" way, with .then, and the issue is still the same.
Your code looks good but if it's a CORS request the server needs to include Access-Control-Expose-Headers: {any custom headers} in the response.
There's a previous question/answer with more details: Reading response headers when using $http of Angularjs
In success callback put :
console.log(headers('content-type'));
console.log(headers()); // All headers
I think the first line return a result in your cas.
In the seconde, have you got the 'Authentication' ?
The custom headers will be visible in same domain. In crossdomain case, you need to send Access-Control-Expose-Headers: Authentication, ... header from server.

AngularJS POST fails with No 'Access-Control-Allow-Origin' when using data payload object but works using query params like payload

I am facing a weird issue. I am running my angularjs app in nodejs server locally which calls a POST API from my app located on Google App Engine. The API is configured with all CORS headers required as follows:
def post(self):
self.response.headers.add_header("Access-Control-Allow-Origin", "*")
self.response.headers.add_header("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,OPTIONS")
self.response.headers.add_header("Access-Control-Allow-Headers", "X-Requested-With, content-type, accept, myapp-domain")
self.response.headers["Content-Type"] = “application/json; charset=utf-8”
GET requests to the API work without issues.
POST requests to the API work but ONLY when I send the post data as a 'string of params' and NOT when post data is sent as an object which is the right way to do. Eventually I need to be able to upload pictures using this API so the first solution below might not work for me. Please help!
METHOD 1: This works:
postMessageAPI = "https://myapp-qa.appspot.com/message";
var postData = "conversationid=1c34b4f2&userid=67e80bf6&content='Hello champs! - Web App'";
var postConfig = {
headers: {
"MYAPP-DOMAIN" : "myapp.bz",
'Content-Type': 'application/json; charset=UTF-8'
}
};
$http.post(postMessageAPI, postData, postConfig).
success(function(data){
$log.log("POST Message API success");
}).
error(function(data, status) {
$log.error("POST Message API FAILED. Status: "+status);
$log.error(JSON.stringify(postData));
});
METHOD 2: This fails:
postMessageAPI = "https://myapp-qa.appspot.com/message";
var postData = ({
'conversationid' : '1c34b4f2',
'userid' : '67e80bf6',
'content' : 'Hello champs! - Web App'
});
var postConfig = {
headers: {
"MYAPP-DOMAIN" : "myapp.bz"
'Content-Type': 'application/json; charset=UTF-8'
}
};
$http.post(postMessageAPI, postData, postConfig).
success(function(data){
$log.log("POST Message API success");
}).
error(function(data, status) {
$log.error("POST Message API FAILED. Status: "+status);
$log.error(JSON.stringify(postData));
});
When I use METHOD 2 it fails with the following error in the console:
XMLHttpRequest cannot load https://myapp-qa.appspot.com/message.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://0.0.0.0:8000' is therefore not allowed access.
Please let me know if you have any solution. Thanks in advance.
The issue is most likely with Angular sending a pre-flight OPTIONS request to check the access headers from the server. I am not sure how OPTIONS requests are handled in your API, but I am betting these headers are not being added. I suggest installing Fiddler to monitor the actual requests to see what is going on with the headers. You may only be adding them to your POST responses.
See this answer for details on why METHOD 1 may work in this scenario, while METHOD 2 does not.
Here are some more details about pre-flight requests.

Resources