add feature for jwt token refresh when token is expired

This commit is contained in:
Eleven 2021-04-09 16:01:03 +08:00
parent b7c487697a
commit 394b9dd59a
6 changed files with 97 additions and 36 deletions

View File

@ -58,14 +58,21 @@ public class LoginInterceptor extends BaseJpomInterceptor {
notLogin = handlerMethod.getBeanType().getAnnotation(NotLogin.class);
}
if (notLogin == null) {
//
int code = this.checkHeaderUser(request, session);
if (code > 0) {
if (!this.tryGetHeaderUser(request, session)) {
// 这里需要判断请求头里是否有 Authorization 属性
String authorization = request.getHeader(ServerOpenApi.HTTP_HEAD_AUTHORIZATION);
if (!StrUtil.isEmpty(authorization)) {
// jwt token 检测机制
int code = this.checkHeaderUser(request, session);
if (code > 0) {
this.responseLogin(request, response, handlerMethod, code);
return false;
}
}
// 老版本登录拦截
if (!this.tryGetHeaderUser(request, session)) {
this.responseLogin(request, response, handlerMethod, ServerConfigBean.AUTHORIZE_TIME_OUT_CODE);
return false;
}
}
reload();
//
@ -92,21 +99,21 @@ public class LoginInterceptor extends BaseJpomInterceptor {
}
return ServerConfigBean.RENEWAL_AUTHORIZE_CODE;
}
UserModel user = (UserModel) session.getAttribute(SESSION_NAME);
UserService userService = SpringUtil.getBean(UserService.class);
UserModel newUser = userService.checkUser(claims.getId());
if (newUser == null) {
return ServerConfigBean.AUTHORIZE_TIME_OUT_CODE;
}
if (null != user) {
String tokenUserId = JwtUtil.readUserId(claims);
boolean b = user.getId().equals(tokenUserId) && user.getUserMd5Key().equals(claims.getId())
&& user.getModifyTime() == newUser.getModifyTime();
if (!b) {
return ServerConfigBean.AUTHORIZE_TIME_OUT_CODE;
}
}
session.setAttribute(LoginInterceptor.SESSION_NAME, newUser);
// UserModel user = (UserModel) session.getAttribute(SESSION_NAME);
// UserService userService = SpringUtil.getBean(UserService.class);
// UserModel newUser = userService.checkUser(claims.getId());
// if (newUser == null) {
// return ServerConfigBean.AUTHORIZE_TIME_OUT_CODE;
// }
// if (null != user) {
// String tokenUserId = JwtUtil.readUserId(claims);
// boolean b = user.getId().equals(tokenUserId) && user.getUserMd5Key().equals(claims.getId())
// && user.getModifyTime() == newUser.getModifyTime();
// if (!b) {
// return ServerConfigBean.AUTHORIZE_TIME_OUT_CODE;
// }
// }
// session.setAttribute(LoginInterceptor.SESSION_NAME, newUser);
return 0;
}

View File

@ -227,7 +227,7 @@ public class LoginControl extends BaseServerController {
@ResponseBody
@NotLogin
public String renewalToken() {
String token = getRequest().getHeader(ServerOpenApi.USER_TOKEN_HEAD);
String token = getRequest().getHeader(ServerOpenApi.HTTP_HEAD_AUTHORIZATION);
if (StrUtil.isEmpty(token)) {
return JsonMessage.getString(ServerConfigBean.AUTHORIZE_TIME_OUT_CODE, "刷新token失败");
}

View File

@ -2,7 +2,9 @@ import Vue from 'vue';
import axios from 'axios';
import Qs from 'qs';
import store from '../store';
import router from '../router';
import { NO_NOTIFY_KEY, NO_LOADING_KEY,TOKEN_HEADER_KEY} from '../utils/const';
import { refreshToken } from './user';
import { notification } from 'ant-design-vue';
@ -65,6 +67,12 @@ request.interceptors.response.use(response => {
// 判断返回值,权限等...
const res = response.data;
// 先判断 jwt token 状态
if (res.code === 800 || res.code === 801) {
return checkJWTToken(res, response);
}
// 其他情况
if (res.code !== 200) {
// 如果 headers 里面配置了 tip: no 就不用弹出提示信息
if (!response.config.headers[NO_NOTIFY_KEY]) {
@ -75,12 +83,7 @@ request.interceptors.response.use(response => {
});
}
}
// 如果是登录信息失效
if (res.code === 800) {
store.dispatch('logOut').then(() => {
location.reload();
})
}
return res;
}, error => {
// 如果 headers 里面配置了 loading: no 就不用 loading
@ -107,4 +110,47 @@ request.interceptors.response.use(response => {
return Promise.reject(error);
});
// 判断 jwt token 状态
function checkJWTToken(res, response) {
// 如果是登录信息失效
if (res.code === 800) {
notification.warn({
message: res.msg,
description: response.config.url,
duration: 3
});
store.dispatch('logOut').then(() => {
router.push('/login');
});
return false;
}
// 如果 jwt token 还可以续签
if (res.code === 801) {
notification.close();
notification.info({
message: '登录信息过期,尝试自动续签...',
description: '如果不需要自动续签,请修改配置文件。该续签将不会影响页面。',
duration: 3
});
// 续签且重试请求
return redoRequest(response.config);
}
}
// 刷新 jwt token 并且重试上次请求
function redoRequest(config) {
return new Promise(resolve => {
Promise.resolve(refreshToken()).then(result => {
if (result.code === 200) {
// 调用 store action 存储当前登录的用户名和 token
store.dispatch('login', result.data);
resolve();
}
});
}).then(() => {
// 重试原来的请求
return request(config);
});
}
export default request

View File

@ -9,6 +9,14 @@ export function login(params) {
})
}
// refresh token
export function refreshToken() {
return axios({
url: '/renewal',
method: 'post'
})
}
// 获取用户信息
export function getUserInfo() {
return axios({

View File

@ -248,7 +248,7 @@ export default {
<style scoped>
.user-header {
display: inline-table;
width: 350px;
width: 300px;
text-align: right;
margin-right: 20px;
cursor: pointer;

View File

@ -27,16 +27,16 @@ const user = {
setToken(state, data) {
state.token = data.token || '';
state.longTermToken = data.longTermToken || '';
if(state.token){
localStorage.setItem(TOKEN_KEY, data.token);
}else{
localStorage.removeItem(TOKEN_KEY);
if (state.token) {
localStorage.setItem(TOKEN_KEY, data.token);
} else {
localStorage.removeItem(TOKEN_KEY);
}
if (state.longTermToken) {
localStorage.setItem(LONG_TERM_TOKEN, data.longTermToken);
} else {
localStorage.removeItem(LONG_TERM_TOKEN);
}
if(state.longTermToken){
localStorage.setItem(LONG_TERM_TOKEN, data.longTermToken);
}else{
localStorage.removeItem(LONG_TERM_TOKEN);
}
},
setUserInfo(state, userInfo) {
state.userInfo = userInfo