angularjs – 使用angular和express-jwt实现刷新令牌
我想使用angular,nodejs和express-jwt实现带有json web令牌的Sliding expiration概念.我对如何做到这一点感到困惑,并且正在努力寻找任何刷新令牌或与这些技术/框架的会话相关的其他材料的例子.
我想到的一些选择是 >初始登录后,为每个请求生成一个新令牌 但我老实说不确定,请帮忙
我设法实现了这个场景.
我做了什么…… 在服务器上: – 为登录启用API端点.此端点将在标头中使用Json Web Token进行响应.客户端必须捕获它(使用$http拦截器)并保存它(我使用本地存储).客户端还将管理服务器发送的刷新令牌. – 对服务器的每个请求都在express中配置中间件以验证令牌.起初我尝试了express-jwt模块,但jsonwebtoken对我来说是正确的. 对于特定路由,您可能需要禁用中间件.在这种情况下登录和注销. var jwtCheck = auth.verifyJWT; jwtCheck.unless = unless; app.use('/api',jwtCheck.unless({path: [ '/api/auth/signin','/api/auth/signout' ]})); – 中间件verifyJWT始终以标头中的令牌响应.如果需要刷新令牌,则调用刷新的函数. jwtLib是我自己的库,其中代码用于创建,刷新和获取jwt令牌. function(req,res,next) { var newToken,token = jwtLib.fetch(req.headers); if(token) { jwt.verify(token,config.jwt.secret,{ secret: config.jwt.secret },function(err,decoded) { if(err) { return res.status(401).send({ message: 'User token is not valid' }); } //Refresh: If the token needs to be refreshed gets the new refreshed token newToken = jwtLib.refreshToken(decoded); if(newToken) { // Set the JWT refreshed token in http header res.set('Authorization','Bearer ' + newToken); next(); } else { res.set('Authorization','Bearer ' + token); next(); } }); } else { return res.status(401).send({ message: 'User token is not present' }); } }; – 刷新功能(jwtLib).由于参数需要解码的令牌,请参阅上面的jsonwebtoken在调用jwt.verify()时解析解码. 如果您在登录期间创建一个有效期为4小时并且刷新到期时间为1小时(1 * 60 * 60 = 3600秒)的令牌,则表示如果用户已处于非活动状态3小时或更长时间,则会刷新令牌,但不超过4小时,因为在这种情况下验证过程将失败(1小时刷新窗口).这样可以避免在每个请求上生成新令牌,但前提是令牌将在此时间窗口中到期. module.exports.refreshToken = function(decoded) { var token_exp,now,newToken; token_exp = decoded.exp; now = moment().unix().valueOf(); if((token_exp - now) < config.jwt.TOKEN_REFRESH_EXPIRATION) { newToken = this.createToken(decoded.user); if(newToken) { return newToken; } } else { return null; } }; 在客户端(Angularjs): – 允许客户端登录.这会调用服务器端点.我使用用base64编码的Http Basic Authentication. //Base64 encode Basic Authorization (email:password) $http.defaults.headers.common.Authorization = 'Basic ' + base64.encode(credentials.email + ':' + credentials.password); return $http.post('/api/auth/signin',{skipAuthorization: true}); – 配置http拦截器以在每次请求时将令牌发送到服务器并将令牌存储在响应上.如果收到刷新的令牌,则必须存储该令牌. // Config HTTP Interceptors angular.module('auth').config(['$httpProvider',function($httpProvider) { // Set the httpProvider interceptor $httpProvider.interceptors.push(['$q','$location','localStorageService','jwtHelper','$injector',function($q,$location,localStorageService,jwtHelper,$injector) { return { request: function(config) { var token = localStorageService.get('authToken'); config.headers = config.headers || {}; if (token && !jwtHelper.isTokenExpired(token)) { config.headers.Authorization = 'Bearer ' + token; } return config; },requestError: function(rejection) { return $q.reject(rejection); },response: function(response) { //JWT Token: If the token is a valid JWT token,new or refreshed,save it in the localStorage var Authentication = $injector.get('Authentication'),storagedToken = localStorageService.get('authToken'),receivedToken = response.headers('Authorization'); if(receivedToken) { receivedToken = Authentication.fetchJwt(receivedToken); } if(receivedToken && !jwtHelper.isTokenExpired(receivedToken) && (storagedToken !== receivedToken)) { //Save Auth token to local storage localStorageService.set('authToken',receivedToken); } return response; },responseError: function(rejection) { var Authentication = $injector.get('Authentication'); switch (rejection.status) { case 401: // Deauthenticate the global user Authentication.signout(); break; case 403: // Add unauthorized behaviour break; } return $q.reject(rejection); } }; } ]); } ]); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |