Javascript 如何使用 AngularJS 在浏览器 cookie 中存储身份验证不记名令牌
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34545875/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to store authentication bearer token in browser cookie using AngularJS
提问by Bimal Das
I have created a bearer token using ASP.net Identity. In AngularJS I wrote this function to get authorized data.
我使用 ASP.net Identity 创建了一个不记名令牌。在 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 :(");
});
};
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.
所以我想将此令牌存储到 Browser cookies 中。如果此令牌存在于那里,则获取令牌并从 IIS 服务器获取数据,否则重定向到登录页面以登录以获取新令牌。
Similarly, if user click onto log out button, it should remove the token from browser cookie.
同样,如果用户点击注销按钮,它应该从浏览器 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 ?
这该怎么做 ?这可能吗?对用户进行身份验证和授权是否正确?如果有多个用户令牌怎么办?
回答by Boris
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
.
我建议不要将数据保存在 cookie 中,出于安全目的,您应该将 cookie 设置为安全和 HttpOnly(无法从 javascript 访问)。如果您不使用 SSL,我建议您移至https
.
I would pass the token from the auth endpoint in a json response:
我会在 json 响应中从 auth 端点传递令牌:
{
tokenData: 'token'
}
You can save the token data in sessionStorage
by using the $window
service:
您可以sessionStorage
使用该$window
服务保存令牌数据:
$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):
用于捕获数据的拦截器实现,改编自 cbass(未测试,您可以检查响应/请求的对象以摆弄信息):
//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'];
回答by cbass
There is a $cookies
service available in the AngularJS API using the
ngCookies
module. It can be used like below:
有一个$cookies
在使用了AngularJS API可用的服务
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'];
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 modulecode. And add it to your angular app: angular.module('myApp', ['ngCookies']);
. Docs for Angular Cookies.
您还必须添加angular-cookies 模块代码。并把它添加到您的角度应用:angular.module('myApp', ['ngCookies']);
。Angular Cookie 的文档。
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.
我还想建议使用 a Http interceptor
,它将为每个请求设置承载标头,而不必为每个请求手动设置它。
//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.
拥有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']
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.
正如鲍里斯所说:还有其他方法可以解决这个问题。您也可以localStorage
用来存储令牌。这也可以与 http 拦截器一起使用。只需将实现从 cookie 更改为 localStorage。
function controller($window) {
//set token
$window.localStorage['jwt']="myToken";
//get token
var token=$window.localStorage['jwt'];
}
controller.$inject=['$window'];