I'm trying to add the 'Authorization' header containing a token for future HTTP request. Retrieval of the token seems to be fine however when making a get request it fails with an Unauthorized error message. After checking the request headers Authorization header does not exist in the request block...
window.crUtil = /*window.crUtil ||*/ (function() {
// Angular Services
var $injector = angular.injector(['ng']);
var $http = $injector.get('$http');
// getting the CFF data
function get_data() {
getJWTAWS();
var url = '/AWS/getDATA/555';
console.log('AUTH header before call: ' + $http.defaults.headers.common.Authorization);
$http.get(url,httpHeader).then(function successCallback(response) {
var data = response.data;
var cff = initCff();
alert(data.itemId);
}, function errorCallback(response) {
initCff();
alert("Error while getting data ");
});
}
function getJWTAWS() {
var httpConfig = {
cache: true,
params: {}
};
$http.get('/AWS/token', httpConfig).then(
function(response) {
if (response.data.accessToken) {
// add jwt token to auth header for all requests made by the $http service
$http.defaults.headers.common.Authorization = response.data.tokenType + ' ' + response.data.accessToken;
}
},
function(error) {
alert('jwt token could not be retrieved.');
}
);
}
})();
var result = util.get_data();
console.log ('called search function ' + result);
Function getToken() returns a value but as I'm new on that topic I'm not quite sure if the way I added the token to the headers is proper.
Could you please advise on the proper way to include the headers in the request. I also tried to add it to the get request like
$http.get(URL,httpHeaders)...
but it also didn't work.
I'm not sure I understand your problem completely as you did not provide what you call
httpConfig
If you're struggling to declare the headers, try making the get request like this:
$http({
method: 'GET',
url: YOUR_URL,
headers: {
'Content-Type': 'application/json',
'Authorization': AUTH_STRING_HERE
}
}).then(function (response) { ... });
You can add any headers you like in the headers object there.
Try adding this in your config block and set the token in your rootscope
$httpProvider.interceptors.push({
request: function (config) {
config.headers.Authorization = $rootScope.token;
return config;
}
})
Related
I am new to auth0 Here, I am getting an JWT-Token in the login request .
So, Lets say, "12344566" thie is the JWT-Token. now , I have now stored this in the localstorage .
jwtOptionsProvider.config({
tokenGetter: function() {
return localStorage.getItem("AuthToken");
},
});
$httpProvider.interceptors.push('jwtInterceptor');
I am using jwtInterceptor for sendig this token in every request . Now,
below is my request ->
addToOntology: function (ontologyName, currentNode, orphan, type) {
var config = {};
config.headers = {
"Content-Type": "application/json",
};
var jsonData = {
"ontologyName": ontologyName,
"orphanName": orphan,
"orphanType": type
};
return $http.put('abv/ontology/' + currentNode.name, jsonData, config)
.then(function (success) {
return success;
},
function (error) {
$log.error(error);
return $q.reject(error);
});
},
Now, If you see here this is my service which is calling a rest api . Here I am sending jsonData . Right now with this code Authorization Bearer 123456 This gets added in header but the jsonData is not getting converted in the jwt . So, How can I do this ? Thanks in advance.
I have an issue at the moment with the google url shortener.
I have set up this service:
angular.module('widget.core').service('urlShortener', service);
function service($log, $q, $http) {
var gapiKey = '<MyApiKey>';
var gapiUrl = 'https://www.googleapis.com/urlshortener/v1/url';
return {
shorten: shorten
};
//////////////////////////////////////////////////
function shorten(url) {
console.log(url);
var data = {
method: 'POST',
url: gapiUrl + '?key=' + gapiKey,
headers: {
'Content-Type': 'application/json',
},
data: {
longUrl: url,
}
};
return $http(data).then(function (response) {
$log.debug(response);
return response.data;
}, function (response) {
$log.debug(response);
return response.data;
});
};
};
As far as I can tell, this should work. I have put in the correct API key and when I run this method I get this error:
{
error: {
code: 401,
message: 'Invalid credentials'
}
}
But, if I use postman and set it up exactly like this method:
Make it post
Add the content-type header and set it to application/json
set the url to https://www.googleapis.com/urlshortener/v1/url?key=myapikey
set the body to:
{
longUrl: 'myreallylogurl.com'
}
When I post this, it works with no issues.
I have checked my application on the google console and it is definitely set to unrestricted.
Has anyone come across this issue before? Does anyone know how to solve it?
I figured this out, it was nothing to do with the code above, but I thought I would answer my own question because someone else may run into the same issue.
In the project I have an httpInterceptor set up that adds the authetentication token to each request for talking to my API. This was what was causing the issue.
It so happened that I already defined a constant for my apiUrl, so I just updated the interceptor to check to make sure that the request url was my api before trying to append the token.
Like this:
angular.module('widget.core').factory('authInterceptor', factory);
function factory($q, $location, $localStorage, apiUrl) {
// The request function
var request = function (config) {
// If we are querying our API
if (config.url.indexOf(apiUrl) > -1) {
// Get our stored auth data
var authData = angular.fromJson($localStorage.get('authorizationData'));
// Set our headers to the request headers or a new object
config.headers = config.headers || {};
// If we have any auth data
if (authData && authData.authenticated) {
// Set our authorization header
config.headers.Authorization = 'Bearer ' + authData.token;
}
}
// Return our config
return config;
};
return {
request: request
};
};
I hope that helps someone else. Took me hours to figure it out :/
I have a factory which returns token as
var accessToken = Restangular.all(url);
accessToken.one('token').get()
.then(function(res) {
deferred.resolve(res.data);
})
.catch(function(errRes) {
deferred.reject(errRes);
});
return deferred.promise;
In my header Interceptor, I need to get the token. Tried below code :
var accessToken;
$injector.get('tokenService').accessToken().then(function(res) {
accessToken = res.access_token;
}, function(e) {
// error
});
req.headers = _.extend({
'Authorization': 'Bearer ' + accessToken
}, req.headers);
Every time I get accessToken as undefined. There should be an easy way to achieve this.
Because you are forming req.headers outside accessToken()'s ajax call. Which tend to make your res.headers object with undefined access_token. Ideally you should wait until accessToken() ajax gets complete & set your res.headers code inside accessToken().then.
Factory
var accessToken = Restangular.all(url);
return accessToken.one('token').get()
.then(function(res) {
return res.data;
})
.catch(function(errRes) {
return errRes;
});
}
Interceptor
var accessToken;
$injector.get('tokenService').accessToken().then(function(res) {
accessToken = res.access_token;
req.headers = _.extend({
'Authorization': 'Bearer ' + accessToken
}, req.headers);
}, function(e) {
// error
});
I have a problem and don´t know how to solve it...
I have to authenticate a user in my IonicApp through a token based authentication. So i have to store the token inside the app, which shouldn´t be a problem...
The Problem is: How can i get the token?
Here´s my code:
// Alle Aufrufe an die REST-Api werden hier durchgeführt
var httpCall = {
async : function(method, url, header, params, data) {
// if (url != 'login') {
// header['X-Auth-Token'] = userTokenFactory.getUserToken();
// }
//console.log(header['X-Auth-Token']);
var ipurl = "IPURL";
// $http returns a promise, which has a then function, which also returns a promise
var promise = $http({
method : method,
url : ipurl + url,
//headers : header,
params : params,
data : data,
config : {
timeout : 5000
}
}).then(function successCallback(response) {
//console.log("data:" + response.data);
//console.log("header:" + response.headers);
console.log("token:" + response.headers['X-AUTH-TOKEN']);
//console.log(response.data.token);
console.log("token" + repsonse.token);
// TRY TO READ THE X_AUTH_TOKEN HERE !!!!!!!!!!!!
return response;
}, function errorCallback(response) {
return response;
});
// Return the promise to the controller
return promise;
}
};
return httpCall;
});
And here´s a picture of the Response from the Server (from Firefox). As you can see, the X-Auth-Token is there...
here´s the x-auth-token
Thanks for the help!!
There are lot of articles are available over handling authentication in AngularJS. This article is the one perfect suitable in your case.
So you can get token from your request as,
}).then(function successCallback(response) {
console.log("data:" + response.data);
$window.sessionStorage.token = response.data.token;
return response;
}, function errorCallback(response) {
return response;
});
Now we have the token saved in sessionStorage. This token can be sent back with each request by at least three ways
1. Set header in each request:
`$http({method: 'GET', url: url, headers: {
'Authorization': 'Bearer ' + $window.sessionStorage.token}
});`
2. Setting defaults headers
`$http.defaults.headers.common['X-Auth-Token'] = 'Bearer ' + $window.sessionStorage.token;`
3. Write Interceptor:
Interceptors give ability to intercept requests before they are
handed to the server and responses before they are handed over to the
application code that initiated these requests
myApp.factory('authInterceptor', function ($rootScope, $q, $window) {
return {
request: function (config) {
config.headers = config.headers || {};
if ($window.sessionStorage.token) {
config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token;
}
return config;
},
response: function (response) {
if (response.status === 401) {
// handle the case where the user is not authenticated
}
return response || $q.when(response);
}
};
});
myApp.config(function ($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
});
Refer AngularJS $http guide for detailed explanation.
As you are getting response.data null and image demonstrates that headers are being returned, I would suggest you to check if you are getting data with
response.headers(),
if then try with response.headers()["X_AUTH_TOKEN"].
I have created a bearer token using ASP.net Identity. In AngularJS I wrote this function to get authorized data.
$scope.GetAuthorizeData = function () {
$http({
method: 'GET',
url: "/api/Values",
headers: { 'authorization': 'bearer <myTokenId>' },
}).success(function (data) {
alert("Authorized :D");
$scope.values = data;
}).error(function () {
alert("Failed :(");
});
};
So I want to store this token into Browser cookies. If this token is present there , then take the token and get the data from IIS server Otherwise redirect to login page to login to get a new token.
Similarly, if user click onto log out button, it should remove the token from browser cookie.
How to do this ? It it possible ? Is it proper way to authenticate and authorize a user ? What to do if there are multiple users token ?
There is a $cookies service available in the AngularJS API using the
ngCookies module. It can be used like below:
function controller($cookies) {
//set cookie
$cookies.put('token', 'myBearerToken');
//get cookie
var token=$cookies.get('token');
//remove token
$cookies.remove('token');
}
controller.$inject=['$cookies'];
For your case it would be:
//inject $cookies into controller
$scope.GetAuthorizeData = function () {
$http({
method: 'GET',
url: "/api/Values",
headers: { 'authorization': 'bearer <myTokenId>' },
})
.success(function (data) {
$cookies.put('token', data);
}).error(function () {
alert("Failed :(");
});
};
You will also have to add the angular-cookies module code. And add it to your angular app: angular.module('myApp', ['ngCookies']);. Docs for Angular Cookies.
I would also like to suggest the usage of a Http interceptor which will set the bearer header for each request, rather than having to manually set it yourself for each request.
//Create a http interceptor factory
function accessTokenHttpInterceptor($cookies) {
return {
//For each request the interceptor will set the bearer token header.
request: function($config) {
//Fetch token from cookie
var token=$cookies.get['token'];
//set authorization header
$config.headers['Authorization'] = 'Bearer '+token;
return $config;
},
response: function(response) {
//if you get a token back in your response you can use
//the response interceptor to update the token in the
//stored in the cookie
if (response.config.headers.yourTokenProperty) {
//fetch token
var token=response.config.headers.yourTokenProperty;
//set token
$cookies.put('token', token);
}
return response;
}
};
}
accessTokenHttpInterceptor.$inject=['$cookies'];
//Register the http interceptor to angular config.
function httpInterceptorRegistry($httpProvider) {
$httpProvider.interceptors.push('accessTokenHttpInterceptor');
}
httpInterceptorRegistry.$inject=['$httpProvider'];
//Assign to module
angular
.module('myApp')
.config(httpInterceptorRegistry)
.factory('accessTokenHttpInterceptor', accessTokenHttpInterceptor)
Having the http interceptor in place you do not need to set the Authorization header for each request.
function service($http) {
this.fetchToken=function() {
//Authorization header will be set before sending request.
return $http
.get("/api/some/endpoint")
.success(function(data) {
console.log(data);
return data;
})
}
}
service.$inject=['$http']
As stated by Boris: there are other ways to solve this. You could also use localStorage to store the token. This can also be used with the http interceptor. Just change the implementation from cookies to localStorage.
function controller($window) {
//set token
$window.localStorage['jwt']="myToken";
//get token
var token=$window.localStorage['jwt'];
}
controller.$inject=['$window'];
I would advise against keeping the data in a cookie, for security purposes you should set the cookies to secure and HttpOnly (not accessible from javascript). If you're not using SSL, I would suggest moving to https.
I would pass the token from the auth endpoint in a json response:
{
tokenData: 'token'
}
You can save the token data in sessionStorage by using the $window service:
$window.sessionStorage.setItem('userInfo-token', 'tokenData');
It will be cleared once the user closes the page, and you can manually remove it by setting it to empty string:
$window.sessionStorage.setItem('userInfo-token', '');
Edit:
Interceptor implementation for catching data, adapted from cbass (not tested, you can inspect the objects for response/request to fiddle with the information):
//Create a http interceptor factory
function accessTokenHttpInterceptor($window) {
return {
//For each request the interceptor will set the bearer token header.
request: function($config) {
//Fetch token from cookie
var token=$window.sessionStorage.getItem('userInfo-token');
//set authorization header
$config.headers['Authorization'] = 'Bearer '+token;
return $config;
},
response: function(response) {
//if you get a token back in your response you can use
//the response interceptor to update the token in the
//stored in the cookie
if (response.config.url === 'api/token' && response.config.data.tokenData) {
//fetch token
var token=response.config.data.tokenData;
//set token
$window.sessionStorage.setItem('userInfo-token', token);
}
return response;
}
};
}
accessTokenHttpInterceptor.$inject=['$window'];