How to store authentication bearer token in browser cookie using AngularJS
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'];