Мне удалось реализовать этот сценарий.
Что я сделал ...
На сервере:
-Enable АНИ конечная точка для входа в аккаунт. Эта конечная точка ответит Json Web Token в заголовке. Клиентская сторона должна поймать его (с помощью перехватчиков $ http) и сохранить его (я использую локальное хранилище). Клиент также будет управлять обновленными токенами, отправленными сервером.
-При каждом запросе серверу настройте промежуточное ПО в выражении для проверки токена. Сначала я попробовал модуль express-jwt, но jsonwebtoken был для меня правильным.
Для определенных маршрутов вы можете отключить промежуточное программное обеспечение. В этом случае signin и signout.
var jwtCheck = auth.verifyJWT;
jwtCheck.unless = unless;
app.use('/api', jwtCheck.unless({path: [
'/api/auth/signin',
'/api/auth/signout'
]}));
-Попроверочное удостоверение JWT всегда отвечает токеном в заголовке. Если токен необходимо обновить, вызывается обновленная функция.
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):
-enable стороне клиента для входа в систему. Это вызывает конечную точку сервера. Я использую Http Basic Authentication, закодированную с base64. Вы можете использовать угловой модуль base64 для кодирования электронной почты: пароль Обратите внимание, что при успешном выполнении я не храню токен на localStorage или Cookie. Это будет управляться http Interceptor.
//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});
-configure 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);
}
};
}
]);
}
]);
У меня в основном один и тот же вопрос, и отправил свой первый проход подход по адресу: https://stackoverflow.com/questions/27408762/jsonwebtoken-activity-based-expiration-vs-issuing-time-based- expiration – rgwozdz
вы можете использовать https://gist.github.com/Mirodil/952e5932c284a2d205db – Mirodil