forked from github/dataease
Merge pull request #8697 from dataease/pr@dev@perf_login
perf: 前端增加token超时标记以减少shiro后台过期错误日志
This commit is contained in:
commit
3d257a4a32
@ -26,7 +26,6 @@ import io.dataease.plugins.xpack.ldap.dto.response.ValidateResult;
|
||||
import io.dataease.plugins.xpack.ldap.service.LdapXpackService;
|
||||
import io.dataease.plugins.xpack.oidc.service.OidcXpackService;
|
||||
import io.dataease.service.sys.SysUserService;
|
||||
|
||||
import io.dataease.service.system.SystemParameterService;
|
||||
import io.dataease.websocket.entity.WsMessage;
|
||||
import io.dataease.websocket.service.WsService;
|
||||
@ -38,15 +37,14 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
@RestController
|
||||
public class AuthServer implements AuthApi {
|
||||
|
||||
@ -203,11 +201,12 @@ public class AuthServer implements AuthApi {
|
||||
result.put("defaultPwd", DEFAULT_PWD);
|
||||
}
|
||||
}
|
||||
|
||||
Long expireTime = System.currentTimeMillis() + JWTUtils.getExpireTime();
|
||||
TokenInfo tokenInfo = TokenInfo.builder().userId(user.getUserId()).username(username).build();
|
||||
String token = JWTUtils.sign(tokenInfo, realPwd);
|
||||
// 记录token操作时间
|
||||
result.put("token", token);
|
||||
result.put("expireTime", expireTime);
|
||||
ServletUtils.setToken(token);
|
||||
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.LOGIN, SysLogConstants.SOURCE_TYPE.USER, user.getUserId(), null, null, null);
|
||||
authUserService.unlockAccount(username, ObjectUtils.isEmpty(loginType) ? 0 : loginType);
|
||||
|
@ -1,8 +1,8 @@
|
||||
package io.dataease.auth.util;
|
||||
|
||||
import com.auth0.jwt.JWT;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.JWTCreator.Builder;
|
||||
import com.auth0.jwt.JWTVerifier;
|
||||
import com.auth0.jwt.algorithms.Algorithm;
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import com.auth0.jwt.interfaces.Verification;
|
||||
@ -10,7 +10,10 @@ import com.google.gson.Gson;
|
||||
import io.dataease.auth.entity.TokenInfo;
|
||||
import io.dataease.auth.entity.TokenInfo.TokenInfoBuilder;
|
||||
import io.dataease.commons.model.OnlineUserModel;
|
||||
import io.dataease.commons.utils.*;
|
||||
import io.dataease.commons.utils.CommonBeanFactory;
|
||||
import io.dataease.commons.utils.IPUtils;
|
||||
import io.dataease.commons.utils.ServletUtils;
|
||||
import io.dataease.commons.utils.TokenCacheUtils;
|
||||
import io.dataease.plugins.common.exception.DataEaseException;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -77,6 +80,13 @@ public class JWTUtils {
|
||||
return sign(tokenInfo, secret, true);
|
||||
}
|
||||
|
||||
public static Long getExpireTime() {
|
||||
if (ObjectUtils.isEmpty(expireTime)) {
|
||||
expireTime = Objects.requireNonNull(CommonBeanFactory.getBean(Environment.class)).getProperty("dataease.login_timeout", Long.class, 480L);
|
||||
}
|
||||
return expireTime * 60000L;
|
||||
}
|
||||
|
||||
private static boolean tokenValid(OnlineUserModel model) {
|
||||
String token = model.getToken();
|
||||
// 如果已经加入黑名单 则直接返回无效
|
||||
@ -84,10 +94,7 @@ public class JWTUtils {
|
||||
if (invalid) return false;
|
||||
|
||||
Long loginTime = model.getLoginTime();
|
||||
if (ObjectUtils.isEmpty(expireTime)) {
|
||||
expireTime = CommonBeanFactory.getBean(Environment.class).getProperty("dataease.login_timeout", Long.class, 480L);
|
||||
}
|
||||
long expireTimeMillis = expireTime * 60000L;
|
||||
long expireTimeMillis = getExpireTime();
|
||||
// 如果当前时间减去登录时间小于超时时间则说明token未过期 返回有效状态
|
||||
return System.currentTimeMillis() - loginTime < expireTimeMillis;
|
||||
|
||||
@ -133,10 +140,7 @@ public class JWTUtils {
|
||||
DataEaseException.throwException("MultiLoginError1");
|
||||
}
|
||||
}
|
||||
if (ObjectUtils.isEmpty(expireTime)) {
|
||||
expireTime = CommonBeanFactory.getBean(Environment.class).getProperty("dataease.login_timeout", Long.class, 480L);
|
||||
}
|
||||
long expireTimeMillis = expireTime * 60000L;
|
||||
long expireTimeMillis = getExpireTime();
|
||||
Date date = new Date(System.currentTimeMillis() + expireTimeMillis);
|
||||
Algorithm algorithm = Algorithm.HMAC256(secret);
|
||||
Builder builder = JWT.create()
|
||||
|
@ -1,5 +1,6 @@
|
||||
module.exports = {
|
||||
TokenKey: 'Authorization',
|
||||
TokenExpKey: 'de-login-login-exp',
|
||||
RefreshTokenKey: 'refreshauthorization',
|
||||
LinkTokenKey: 'LINK-PWD-TOKEN',
|
||||
title: 'DataEase',
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { login, logout, deLogout, getInfo, getUIinfo, languageApi } from '@/api/user'
|
||||
import { getToken, setToken, removeToken, setSysUI } from '@/utils/auth'
|
||||
import { getToken, setToken, removeToken, setSysUI, setTokenExp } from '@/utils/auth'
|
||||
import { resetRouter } from '@/router'
|
||||
import { format } from '@/utils/formatUi'
|
||||
import { getLanguage } from '@/lang/index'
|
||||
@ -82,6 +82,7 @@ const actions = {
|
||||
commit('SET_TOKEN', data.token)
|
||||
commit('SET_LOGIN_MSG', null)
|
||||
setToken(data.token)
|
||||
setTokenExp(data.expireTime)
|
||||
let passwordModified = true
|
||||
if (Object.prototype.hasOwnProperty.call(data, 'passwordModified')) {
|
||||
passwordModified = data.passwordModified
|
||||
|
@ -2,6 +2,7 @@ import Cookies from 'js-cookie'
|
||||
import Config from '@/settings'
|
||||
import store from '@/store'
|
||||
const TokenKey = Config.TokenKey
|
||||
const TokenExpKey = Config.TokenExpKey
|
||||
|
||||
const IdTokenKey = Config.IdTokenKey
|
||||
|
||||
@ -22,11 +23,27 @@ export function getToken() {
|
||||
export function setToken(token) {
|
||||
return Cookies.set(TokenKey, token)
|
||||
}
|
||||
export function setTokenExp(exp) {
|
||||
if (exp) {
|
||||
// return Cookies.set(TokenExpKey, exp)
|
||||
return Cookies.set(TokenExpKey, new Date().getTime() + 5000)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
export function tokenExp() {
|
||||
const exp = Cookies.get(TokenExpKey)
|
||||
if (exp && exp > 3000) {
|
||||
return new Date().getTime() > (exp - 3000)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export function removeToken() {
|
||||
Cookies.remove(casSessionKey)
|
||||
Cookies.remove(IdTokenKey)
|
||||
Cookies.remove(AccessTokenKey)
|
||||
Cookies.remove(TokenExpKey)
|
||||
return Cookies.remove(TokenKey)
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import axios from 'axios'
|
||||
import store from '@/store'
|
||||
import { $alert, $error } from './message'
|
||||
import { getToken, getIdToken, setToken } from '@/utils/auth'
|
||||
import { getToken, getIdToken, setToken, tokenExp } from '@/utils/auth'
|
||||
import Config from '@/settings'
|
||||
import i18n from '@/lang'
|
||||
import { tryShowLoading, tryHideLoading } from './loading'
|
||||
@ -56,7 +56,6 @@ service.interceptors.request.use(
|
||||
if (idToken) {
|
||||
config.headers[Config.IdTokenKey] = idToken
|
||||
}
|
||||
|
||||
if (store.getters.token) {
|
||||
config.headers[TokenKey] = getToken()
|
||||
}
|
||||
@ -74,7 +73,26 @@ service.interceptors.request.use(
|
||||
config.headers['Accept-Language'] = lang
|
||||
}
|
||||
config.loading && tryShowLoading(store.getters.currentPath)
|
||||
|
||||
if (config.headers[TokenKey]) {
|
||||
const logoutApiList = ['/api/auth/deLogout', '/api/auth/logout']
|
||||
if (tokenExp() && !logoutApiList.includes(config.url)) {
|
||||
config['expCancel'] = null
|
||||
config.cancelToken = new CancelToken(function executor(c) {
|
||||
config['expCancel'] = c
|
||||
})
|
||||
const message = i18n.t('login.expires')
|
||||
$alert(message, () => {
|
||||
store.dispatch('user/logout').then(() => {
|
||||
location.reload()
|
||||
})
|
||||
}, {
|
||||
confirmButtonText: i18n.t('login.re_login'),
|
||||
showClose: false
|
||||
})
|
||||
config.expCancel('login.expires')
|
||||
return config
|
||||
}
|
||||
}
|
||||
config.cancelToken = new CancelToken(function executor(c) {
|
||||
Vue.prototype.$currentHttpRequestList.set(config.url, c)
|
||||
})
|
||||
@ -104,10 +122,12 @@ service.interceptors.response.use(response => {
|
||||
}
|
||||
return response.data
|
||||
}, error => {
|
||||
const config = error.response && error.response.config || error.config
|
||||
let config = error.response && error.response.config || error.config
|
||||
const headers = error.response && error.response.headers || error.response || config && config.headers
|
||||
config.loading && tryHideLoading(store.getters.currentPath)
|
||||
|
||||
config?.loading && tryHideLoading(store.getters.currentPath)
|
||||
if (!config && !headers && error.code === 'ERR_CANCELED' && error.message === 'login.expires') {
|
||||
config = { hideMsg: true }
|
||||
}
|
||||
let msg = ''
|
||||
|
||||
if (error.response) {
|
||||
@ -119,7 +139,7 @@ service.interceptors.response.use(response => {
|
||||
if (msg.length > 600) {
|
||||
msg = msg.slice(0, 600)
|
||||
}
|
||||
!config.hideMsg && (!headers['authentication-status']) && !msg?.startsWith('MultiLoginError') && $error(msg)
|
||||
!config?.hideMsg && (!headers['authentication-status']) && !msg?.startsWith('MultiLoginError') && $error(msg)
|
||||
return Promise.reject(config.url === '/dataset/table/sqlPreview' ? msg : error)
|
||||
})
|
||||
const checkDownError = response => {
|
||||
|
Loading…
Reference in New Issue
Block a user