如何使用 AngularJS 在浏览器 cookie 中存储身份验证持有者令牌
How to store authentication bearer token in browser cookie using AngularJS
我已经使用 ASP.net 身份创建了不记名令牌。在AngularJS我写了这个函数来获取授权数据。
$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 :(");
});
};
所以我想将此令牌存储到浏览器 cookie 中。如果此令牌存在,则获取令牌并从 IIS 服务器获取数据否则重定向到登录页面以登录以获取新令牌。
同样,如果用户点击注销按钮,它应该从浏览器 cookie 中删除令牌。
怎么做?有可能吗?这是验证和授权用户的正确方法吗?如果有多个用户令牌怎么办?
我建议不要将数据保存在 cookie 中,出于安全目的,您应该将 cookie 设置为安全和 HttpOnly(无法从 javascript 访问)。如果您不使用 SSL,我建议您移至 https
.
我会在 json 响应中从身份验证端点传递令牌:
{
tokenData: 'token'
}
您可以使用 $window
服务将令牌数据保存在 sessionStorage
中:
$window.sessionStorage.setItem('userInfo-token', 'tokenData');
一旦用户关闭页面,它就会被清除,您可以通过将其设置为空字符串来手动删除它:
$window.sessionStorage.setItem('userInfo-token', '');
编辑:
捕获数据的拦截器实现,改编自cbass(未测试,您可以根据信息检查response/request到fiddle的对象):
//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'];
AngularJS API 中有一项 $cookies
服务可用
ngCookies
模块。它可以像下面这样使用:
function controller($cookies) {
//set cookie
$cookies.put('token', 'myBearerToken');
//get cookie
var token=$cookies.get('token');
//remove token
$cookies.remove('token');
}
controller.$inject=['$cookies'];
对于你的情况,它将是:
//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 :(");
});
};
您还必须添加 angular-cookies module code. And add it to your angular app: angular.module('myApp', ['ngCookies']);
. Docs for Angular Cookies.
我还想建议使用 Http interceptor
,它将为每个请求设置承载 header,而不必为每个请求自己手动设置。
//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)
有了 http interceptor
,您就不需要为每个请求设置 Authorization header
。
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']
正如鲍里斯所说:还有其他方法可以解决这个问题。您还可以使用 localStorage
来存储令牌。这也可以与 http 拦截器一起使用。只需将实现从 cookie 更改为 localStorage。
function controller($window) {
//set token
$window.localStorage['jwt']="myToken";
//get token
var token=$window.localStorage['jwt'];
}
controller.$inject=['$window'];
我已经使用 ASP.net 身份创建了不记名令牌。在AngularJS我写了这个函数来获取授权数据。
$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 :(");
});
};
所以我想将此令牌存储到浏览器 cookie 中。如果此令牌存在,则获取令牌并从 IIS 服务器获取数据否则重定向到登录页面以登录以获取新令牌。
同样,如果用户点击注销按钮,它应该从浏览器 cookie 中删除令牌。
怎么做?有可能吗?这是验证和授权用户的正确方法吗?如果有多个用户令牌怎么办?
我建议不要将数据保存在 cookie 中,出于安全目的,您应该将 cookie 设置为安全和 HttpOnly(无法从 javascript 访问)。如果您不使用 SSL,我建议您移至 https
.
我会在 json 响应中从身份验证端点传递令牌:
{
tokenData: 'token'
}
您可以使用 $window
服务将令牌数据保存在 sessionStorage
中:
$window.sessionStorage.setItem('userInfo-token', 'tokenData');
一旦用户关闭页面,它就会被清除,您可以通过将其设置为空字符串来手动删除它:
$window.sessionStorage.setItem('userInfo-token', '');
编辑:
捕获数据的拦截器实现,改编自cbass(未测试,您可以根据信息检查response/request到fiddle的对象):
//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'];
AngularJS API 中有一项 $cookies
服务可用
ngCookies
模块。它可以像下面这样使用:
function controller($cookies) {
//set cookie
$cookies.put('token', 'myBearerToken');
//get cookie
var token=$cookies.get('token');
//remove token
$cookies.remove('token');
}
controller.$inject=['$cookies'];
对于你的情况,它将是:
//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 :(");
});
};
您还必须添加 angular-cookies module code. And add it to your angular app: angular.module('myApp', ['ngCookies']);
. Docs for Angular Cookies.
我还想建议使用 Http interceptor
,它将为每个请求设置承载 header,而不必为每个请求自己手动设置。
//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)
有了 http interceptor
,您就不需要为每个请求设置 Authorization header
。
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']
正如鲍里斯所说:还有其他方法可以解决这个问题。您还可以使用 localStorage
来存储令牌。这也可以与 http 拦截器一起使用。只需将实现从 cookie 更改为 localStorage。
function controller($window) {
//set token
$window.localStorage['jwt']="myToken";
//get token
var token=$window.localStorage['jwt'];
}
controller.$inject=['$window'];