mirror of
https://github.com/FatttSnake/Pinnacle-OA.git
synced 2026-04-06 07:21:24 +08:00
Added token automatic renew
This commit is contained in:
@@ -28,7 +28,7 @@ public class LoginController {
|
|||||||
@PostMapping("/login")
|
@PostMapping("/login")
|
||||||
public ResponseResult<HashMap<String, String>> login(@RequestBody User user) {
|
public ResponseResult<HashMap<String, String>> login(@RequestBody User user) {
|
||||||
HashMap<String, String> hashMap = loginService.login(user);
|
HashMap<String, String> hashMap = loginService.login(user);
|
||||||
return ResponseResult.build(ResponseCode.LOGIN_SUCCESS, "Login Success", hashMap);
|
return ResponseResult.build(ResponseCode.LOGIN_SUCCESS, "Login success", hashMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "登出")
|
@Operation(summary = "登出")
|
||||||
@@ -36,9 +36,17 @@ public class LoginController {
|
|||||||
public ResponseResult<?> logout(HttpServletRequest request) {
|
public ResponseResult<?> logout(HttpServletRequest request) {
|
||||||
boolean result = loginService.logout(request.getHeader("token"));
|
boolean result = loginService.logout(request.getHeader("token"));
|
||||||
if (result) {
|
if (result) {
|
||||||
return ResponseResult.build(ResponseCode.LOGOUT_SUCCESS, "Logout Success", null);
|
return ResponseResult.build(ResponseCode.LOGOUT_SUCCESS, "Logout success", null);
|
||||||
} else {
|
} else {
|
||||||
return ResponseResult.build(ResponseCode.LOGOUT_FAILED, "Logout Failed", null);
|
return ResponseResult.build(ResponseCode.LOGOUT_FAILED, "Logout failed", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "更新 Token")
|
||||||
|
@GetMapping("/token")
|
||||||
|
public ResponseResult<HashMap<String, String >> renewToken(HttpServletRequest request) {
|
||||||
|
String token = request.getHeader("token");
|
||||||
|
HashMap<String, String> hashMap = loginService.renewToken(token);
|
||||||
|
return ResponseResult.build(ResponseCode.TOKEN_RENEW_SUCCESS, "Token renew success", hashMap);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ public class ResponseCode {
|
|||||||
public static final int LOGOUT_FAILED = 20016;
|
public static final int LOGOUT_FAILED = 20016;
|
||||||
public static final int TOKEN_IS_ILLEGAL = 20017;
|
public static final int TOKEN_IS_ILLEGAL = 20017;
|
||||||
public static final int TOKEN_HAS_EXPIRED = 20018;
|
public static final int TOKEN_HAS_EXPIRED = 20018;
|
||||||
|
public static final int TOKEN_RENEW_SUCCESS = 20019;
|
||||||
public static final int DATABASE_SELECT_OK = 20021;
|
public static final int DATABASE_SELECT_OK = 20021;
|
||||||
public static final int DATABASE_SAVE_OK = 20022;
|
public static final int DATABASE_SAVE_OK = 20022;
|
||||||
public static final int DATABASE_UPDATE_OK = 20023;
|
public static final int DATABASE_UPDATE_OK = 20023;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
||||||
@@ -45,6 +46,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
|||||||
if (Objects.isNull(loginUser)) {
|
if (Objects.isNull(loginUser)) {
|
||||||
throw new TokenHasExpiredException();
|
throw new TokenHasExpiredException();
|
||||||
}
|
}
|
||||||
|
redisCache.expire(redisKey, 20, TimeUnit.MINUTES);
|
||||||
|
|
||||||
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
|
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
|
||||||
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
||||||
|
|||||||
@@ -8,4 +8,6 @@ public interface ILoginService {
|
|||||||
HashMap<String, String> login(User user);
|
HashMap<String, String> login(User user);
|
||||||
|
|
||||||
boolean logout(String token);
|
boolean logout(String token);
|
||||||
|
|
||||||
|
HashMap<String, String> renewToken(String token);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.cfive.pinnacle.entity.permission.LoginUser;
|
|||||||
import com.cfive.pinnacle.service.permission.ILoginService;
|
import com.cfive.pinnacle.service.permission.ILoginService;
|
||||||
import com.cfive.pinnacle.utils.JwtUtil;
|
import com.cfive.pinnacle.utils.JwtUtil;
|
||||||
import com.cfive.pinnacle.utils.RedisCache;
|
import com.cfive.pinnacle.utils.RedisCache;
|
||||||
|
import com.cfive.pinnacle.utils.WebUtil;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.authentication.AuthenticationManager;
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
@@ -46,7 +47,7 @@ public class LoginServiceImpl implements ILoginService {
|
|||||||
HashMap<String, String> hashMap = new HashMap<>();
|
HashMap<String, String> hashMap = new HashMap<>();
|
||||||
hashMap.put("token", jwt);
|
hashMap.put("token", jwt);
|
||||||
|
|
||||||
redisCache.setCacheObject("login:" + jwt, loginUser, 30, TimeUnit.MINUTES);
|
redisCache.setCacheObject("login:" + jwt, loginUser, 20, TimeUnit.MINUTES);
|
||||||
|
|
||||||
return hashMap;
|
return hashMap;
|
||||||
}
|
}
|
||||||
@@ -55,4 +56,15 @@ public class LoginServiceImpl implements ILoginService {
|
|||||||
public boolean logout(String token) {
|
public boolean logout(String token) {
|
||||||
return redisCache.deleteObject("login:" + token);
|
return redisCache.deleteObject("login:" + token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HashMap<String, String> renewToken(String token) {
|
||||||
|
String oldRedisKey = "login:" + token;
|
||||||
|
redisCache.deleteObject(oldRedisKey);
|
||||||
|
String jwt = JwtUtil.createJWT(WebUtil.getLoginUser().getUser().getId().toString());
|
||||||
|
HashMap<String, String> hashMap = new HashMap<>();
|
||||||
|
hashMap.put("token", jwt);
|
||||||
|
redisCache.setCacheObject("login:" + jwt, WebUtil.getLoginUser(), 20, TimeUnit.MINUTES);
|
||||||
|
return hashMap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import java.util.UUID;
|
|||||||
public class JwtUtil {
|
public class JwtUtil {
|
||||||
|
|
||||||
// 有效期
|
// 有效期
|
||||||
public static final Long JWT_TTL = 60 * 60 * 1000L; // 60 * 60 * 1000 一个小时
|
public static final Long JWT_TTL = 2 * 60 * 60 * 1000L; // 2 * 60 * 60 * 1000 两个小时
|
||||||
// 秘钥明文
|
// 秘钥明文
|
||||||
public static final String JWT_KEY = "pinnacle";
|
public static final String JWT_KEY = "pinnacle";
|
||||||
//签发者
|
//签发者
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ const LOGOUT_SUCCESS = 20015
|
|||||||
const LOGOUT_FAILED = 20016
|
const LOGOUT_FAILED = 20016
|
||||||
const TOKEN_IS_ILLEGAL = 20017
|
const TOKEN_IS_ILLEGAL = 20017
|
||||||
const TOKEN_HAS_EXPIRED = 20018
|
const TOKEN_HAS_EXPIRED = 20018
|
||||||
|
const TOKEN_RENEW_SUCCESS = 20019
|
||||||
const DATABASE_SELECT_OK = 20021
|
const DATABASE_SELECT_OK = 20021
|
||||||
const DATABASE_SAVE_OK = 20022
|
const DATABASE_SAVE_OK = 20022
|
||||||
const DATABASE_UPDATE_OK = 20023
|
const DATABASE_UPDATE_OK = 20023
|
||||||
@@ -59,6 +60,7 @@ export {
|
|||||||
LOGOUT_FAILED,
|
LOGOUT_FAILED,
|
||||||
TOKEN_IS_ILLEGAL,
|
TOKEN_IS_ILLEGAL,
|
||||||
TOKEN_HAS_EXPIRED,
|
TOKEN_HAS_EXPIRED,
|
||||||
|
TOKEN_RENEW_SUCCESS,
|
||||||
DATABASE_SELECT_OK,
|
DATABASE_SELECT_OK,
|
||||||
DATABASE_SAVE_OK,
|
DATABASE_SAVE_OK,
|
||||||
DATABASE_UPDATE_OK,
|
DATABASE_UPDATE_OK,
|
||||||
|
|||||||
@@ -155,10 +155,10 @@ export default {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
login(this.userName, this.password).then((res) => {
|
login(this.userName, this.password).then((res) => {
|
||||||
const data = res.data
|
const response = res.data
|
||||||
switch (data.code) {
|
switch (response.code) {
|
||||||
case LOGIN_SUCCESS:
|
case LOGIN_SUCCESS:
|
||||||
setToken(data.data.token)
|
setToken(response.data.token)
|
||||||
ElMessage.success({
|
ElMessage.success({
|
||||||
dangerouslyUseHTMLString: true,
|
dangerouslyUseHTMLString: true,
|
||||||
message: '<strong>登录成功</strong>'
|
message: '<strong>登录成功</strong>'
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import axios, { type AxiosError } from 'axios'
|
import axios, { type AxiosError } from 'axios'
|
||||||
import { clearLocalStorage, getToken } from '@/utils/common'
|
import jwtDecode from 'jwt-decode'
|
||||||
|
import { clearLocalStorage, getToken, setToken } from '@/utils/common'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import {
|
import {
|
||||||
ACCESS_DENIED,
|
ACCESS_DENIED,
|
||||||
@@ -7,6 +8,7 @@ import {
|
|||||||
DATABASE_DATA_VALIDATION_FAILED,
|
DATABASE_DATA_VALIDATION_FAILED,
|
||||||
TOKEN_HAS_EXPIRED,
|
TOKEN_HAS_EXPIRED,
|
||||||
TOKEN_IS_ILLEGAL,
|
TOKEN_IS_ILLEGAL,
|
||||||
|
TOKEN_RENEW_SUCCESS,
|
||||||
UNAUTHORIZED
|
UNAUTHORIZED
|
||||||
} from '@/constants/Common.constants'
|
} from '@/constants/Common.constants'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
@@ -18,9 +20,27 @@ const service = axios.create({
|
|||||||
})
|
})
|
||||||
|
|
||||||
service.interceptors.request.use(
|
service.interceptors.request.use(
|
||||||
(config) => {
|
async (config) => {
|
||||||
const token = getToken()
|
let token = getToken()
|
||||||
if (token != null) {
|
if (token != null) {
|
||||||
|
const jwt = jwtDecode(token)
|
||||||
|
if (
|
||||||
|
(jwt as any).exp * 1000 - new Date().getTime() < 1200000 &&
|
||||||
|
(jwt as any).exp * 1000 - new Date().getTime() > 0
|
||||||
|
) {
|
||||||
|
await axios
|
||||||
|
.get('http://localhost:8621/token', {
|
||||||
|
headers: { token }
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
const response = res.data
|
||||||
|
if (response.code === TOKEN_RENEW_SUCCESS) {
|
||||||
|
setToken(response.data.token)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
token = getToken()
|
||||||
config.headers.set('token', token)
|
config.headers.set('token', token)
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
|
|||||||
Reference in New Issue
Block a user