mirror of
https://github.com/FatttSnake/Pinnacle-OA.git
synced 2026-04-04 22:41:24 +08:00
Added login expiration reminder. Add logout reminder.
This commit is contained in:
@@ -92,6 +92,10 @@
|
|||||||
<artifactId>java-jwt</artifactId>
|
<artifactId>java-jwt</artifactId>
|
||||||
<version>4.3.0</version>
|
<version>4.3.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.cfive.pinnacle.entity.common.ResponseCode;
|
|||||||
import com.cfive.pinnacle.entity.common.ResponseResult;
|
import com.cfive.pinnacle.entity.common.ResponseResult;
|
||||||
import com.cfive.pinnacle.service.permission.ILoginService;
|
import com.cfive.pinnacle.service.permission.ILoginService;
|
||||||
import com.cfive.pinnacle.utils.WebUtil;
|
import com.cfive.pinnacle.utils.WebUtil;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@@ -28,8 +29,8 @@ public class LoginController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/logout")
|
@RequestMapping("/logout")
|
||||||
public ResponseResult logout() {
|
public ResponseResult logout(HttpServletRequest request) {
|
||||||
boolean result = loginService.logout();
|
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 {
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ public class ResponseCode {
|
|||||||
public static final int LOGIN_USERNAME_PASSWORD_ERROR = 20011;
|
public static final int LOGIN_USERNAME_PASSWORD_ERROR = 20011;
|
||||||
public static final int LOGOUT_SUCCESS = 20015;
|
public static final int LOGOUT_SUCCESS = 20015;
|
||||||
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_HAS_EXPIRED = 20018;
|
||||||
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;
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package com.cfive.pinnacle.filter;
|
package com.cfive.pinnacle.filter;
|
||||||
|
|
||||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
import com.cfive.pinnacle.entity.common.ResponseCode;
|
||||||
import com.cfive.pinnacle.entity.permission.LoginUser;
|
import com.cfive.pinnacle.entity.permission.LoginUser;
|
||||||
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 com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import jakarta.annotation.Nonnull;
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.ServletException;
|
import jakarta.servlet.ServletException;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
@@ -29,26 +31,29 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
protected void doFilterInternal(HttpServletRequest request, @Nonnull HttpServletResponse response, @Nonnull FilterChain filterChain) throws ServletException, IOException {
|
||||||
String token = request.getHeader("token");
|
String token = request.getHeader("token");
|
||||||
if (!StringUtils.hasText(token)) {
|
if (!StringUtils.hasText(token)) {
|
||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String userId;
|
|
||||||
try {
|
try {
|
||||||
DecodedJWT decodedJWT = JwtUtil.parseJWT(token);
|
JwtUtil.parseJWT(token);
|
||||||
userId = decodedJWT.getSubject();
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Token is illegal");
|
String objectResponse = WebUtil.objectResponse(ResponseCode.TOKEN_IS_ILLEGAL, "Token is illegal", null);
|
||||||
|
WebUtil.renderString(response, objectResponse);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String redisKey = "login:" + userId;
|
String redisKey = "login:" + token;
|
||||||
LoginUser loginUser = new ObjectMapper().convertValue(redisCache.getCacheObject(redisKey), LoginUser.class);
|
LoginUser loginUser = new ObjectMapper().convertValue(redisCache.getCacheObject(redisKey), LoginUser.class);
|
||||||
if (Objects.isNull(loginUser)) {
|
if (Objects.isNull(loginUser)) {
|
||||||
throw new RuntimeException("Not logged in");
|
String objectResponse = WebUtil.objectResponse(ResponseCode.TOKEN_HAS_EXPIRED, "Token has expired", null);
|
||||||
|
WebUtil.renderString(response, objectResponse);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo 权限
|
// Todo 权限
|
||||||
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, null);
|
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, null);
|
||||||
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public class AuthenticationEntryPointHandler implements AuthenticationEntryPoint
|
|||||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
|
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
|
||||||
String objectResponse;
|
String objectResponse;
|
||||||
if (authException instanceof BadCredentialsException) {
|
if (authException instanceof BadCredentialsException) {
|
||||||
objectResponse = WebUtil.objectResponse(ResponseCode.LOGOUT_FAILED, authException.getMessage(), null);
|
objectResponse = WebUtil.objectResponse(ResponseCode.LOGIN_USERNAME_PASSWORD_ERROR, authException.getMessage(), null);
|
||||||
} else if (authException instanceof InsufficientAuthenticationException) {
|
} else if (authException instanceof InsufficientAuthenticationException) {
|
||||||
objectResponse = WebUtil.objectResponse(ResponseCode.UNAUTHORIZED, authException.getMessage(), null);
|
objectResponse = WebUtil.objectResponse(ResponseCode.UNAUTHORIZED, authException.getMessage(), null);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ import java.util.HashMap;
|
|||||||
public interface ILoginService {
|
public interface ILoginService {
|
||||||
HashMap<String, String> login(User user);
|
HashMap<String, String> login(User user);
|
||||||
|
|
||||||
boolean logout();
|
boolean logout(String token);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ 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;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class LoginServiceImpl implements ILoginService {
|
public class LoginServiceImpl implements ILoginService {
|
||||||
@@ -46,17 +46,13 @@ 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:" + userId, loginUser);
|
redisCache.setCacheObject("login:" + jwt, loginUser, 10, TimeUnit.MINUTES);
|
||||||
|
|
||||||
return hashMap;
|
return hashMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean logout() {
|
public boolean logout(String token) {
|
||||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
return redisCache.deleteObject("login:" + token);
|
||||||
LoginUser loginUser = (LoginUser) authentication.getPrincipal();
|
|
||||||
|
|
||||||
Long userId = loginUser.getUser().getId();
|
|
||||||
return redisCache.deleteObject("login:" + userId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.cfive.pinnacle.utils;
|
package com.cfive.pinnacle.utils;
|
||||||
|
|
||||||
import com.cfive.pinnacle.entity.User;
|
|
||||||
import com.cfive.pinnacle.entity.common.ResponseResult;
|
import com.cfive.pinnacle.entity.common.ResponseResult;
|
||||||
import com.cfive.pinnacle.entity.permission.LoginUser;
|
import com.cfive.pinnacle.entity.permission.LoginUser;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
|||||||
@@ -10,6 +10,31 @@ const SIZE_ICON_MD = '24px'
|
|||||||
const SIZE_ICON_LG = '32px'
|
const SIZE_ICON_LG = '32px'
|
||||||
const SIZE_ICON_XL = '64px'
|
const SIZE_ICON_XL = '64px'
|
||||||
|
|
||||||
|
// Response Code
|
||||||
|
const SYSTEM_OK = 20000
|
||||||
|
const LOGIN_SUCCESS = 20010
|
||||||
|
const LOGIN_USERNAME_PASSWORD_ERROR = 20011
|
||||||
|
const LOGOUT_SUCCESS = 20015
|
||||||
|
const LOGOUT_FAILED = 20016
|
||||||
|
const TOKEN_IS_ILLEGAL = 20017
|
||||||
|
const TOKEN_HAS_EXPIRED = 20018
|
||||||
|
const DATABASE_SELECT_OK = 20021
|
||||||
|
const DATABASE_SAVE_OK = 20022
|
||||||
|
const DATABASE_UPDATE_OK = 20023
|
||||||
|
const DATABASE_DELETE_OK = 20024
|
||||||
|
const DATABASE_SELECT_ERROR = 20031
|
||||||
|
const DATABASE_SAVE_ERROR = 20032
|
||||||
|
const DATABASE_UPDATE_ERROR = 20033
|
||||||
|
const DATABASE_DELETE_ERROR = 20034
|
||||||
|
const DATABASE_TIMEOUT_ERROR = 20035
|
||||||
|
const DATABASE_CONNECT_ERROR = 20036
|
||||||
|
|
||||||
|
const UNAUTHORIZED = 30010
|
||||||
|
const ACCESS_DENIED = 30030
|
||||||
|
|
||||||
|
const SYSTEM_ERROR = 50001
|
||||||
|
const SYSTEM_TIMEOUT = 50002
|
||||||
|
|
||||||
export {
|
export {
|
||||||
PRODUCTION_NAME,
|
PRODUCTION_NAME,
|
||||||
TOKEN_NAME,
|
TOKEN_NAME,
|
||||||
@@ -21,5 +46,26 @@ export {
|
|||||||
SIZE_ICON_SM,
|
SIZE_ICON_SM,
|
||||||
SIZE_ICON_MD,
|
SIZE_ICON_MD,
|
||||||
SIZE_ICON_LG,
|
SIZE_ICON_LG,
|
||||||
SIZE_ICON_XL
|
SIZE_ICON_XL,
|
||||||
|
SYSTEM_OK,
|
||||||
|
LOGIN_SUCCESS,
|
||||||
|
LOGIN_USERNAME_PASSWORD_ERROR,
|
||||||
|
LOGOUT_SUCCESS,
|
||||||
|
LOGOUT_FAILED,
|
||||||
|
TOKEN_IS_ILLEGAL,
|
||||||
|
TOKEN_HAS_EXPIRED,
|
||||||
|
DATABASE_SELECT_OK,
|
||||||
|
DATABASE_SAVE_OK,
|
||||||
|
DATABASE_UPDATE_OK,
|
||||||
|
DATABASE_DELETE_OK,
|
||||||
|
DATABASE_SELECT_ERROR,
|
||||||
|
DATABASE_SAVE_ERROR,
|
||||||
|
DATABASE_UPDATE_ERROR,
|
||||||
|
DATABASE_DELETE_ERROR,
|
||||||
|
DATABASE_TIMEOUT_ERROR,
|
||||||
|
DATABASE_CONNECT_ERROR,
|
||||||
|
UNAUTHORIZED,
|
||||||
|
ACCESS_DENIED,
|
||||||
|
SYSTEM_ERROR,
|
||||||
|
SYSTEM_TIMEOUT
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import router from '@/router'
|
|||||||
import '@/assets/css/base.css'
|
import '@/assets/css/base.css'
|
||||||
import '@/assets/css/common.css'
|
import '@/assets/css/common.css'
|
||||||
|
|
||||||
|
import 'element-plus/theme-chalk/el-message.css'
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
app.use(router).mount('#app')
|
app.use(router).mount('#app')
|
||||||
|
|||||||
@@ -80,8 +80,8 @@
|
|||||||
import { getCaptchaSrc, login, verifyCaptcha } from '@/utils/auth'
|
import { getCaptchaSrc, login, verifyCaptcha } from '@/utils/auth'
|
||||||
import backShape from '@/assets/svg/back-shape.svg'
|
import backShape from '@/assets/svg/back-shape.svg'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import 'element-plus/theme-chalk/el-message.css'
|
import { LOGIN_SUCCESS, PRODUCTION_NAME } from '@/constants/Common.constants'
|
||||||
import { PRODUCTION_NAME } from '@/constants/Common.constants'
|
import { setToken } from '@/utils/common'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'LoginPage',
|
name: 'LoginPage',
|
||||||
@@ -102,7 +102,8 @@ export default {
|
|||||||
getNewCaptcha() {
|
getNewCaptcha() {
|
||||||
this.captchaSrc = getCaptchaSrc()
|
this.captchaSrc = getCaptchaSrc()
|
||||||
},
|
},
|
||||||
async login() {
|
login() {
|
||||||
|
const _this = this
|
||||||
if (!this.userName) {
|
if (!this.userName) {
|
||||||
ElMessage.error({
|
ElMessage.error({
|
||||||
dangerouslyUseHTMLString: true,
|
dangerouslyUseHTMLString: true,
|
||||||
@@ -131,22 +132,25 @@ export default {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (await login(this.userName, this.password)) {
|
login(this.userName, this.password).then((res) => {
|
||||||
ElMessage.success({
|
const data = res.data
|
||||||
dangerouslyUseHTMLString: true,
|
if (data.code === LOGIN_SUCCESS) {
|
||||||
message: '<strong>登录成功</strong>'
|
setToken(data.data.token)
|
||||||
})
|
ElMessage.success({
|
||||||
this.loggingIn = true
|
dangerouslyUseHTMLString: true,
|
||||||
const _this = this
|
message: '<strong>登录成功</strong>'
|
||||||
setTimeout(function () {
|
})
|
||||||
_this.$router.push('/')
|
this.loggingIn = true
|
||||||
}, 1500)
|
setTimeout(function () {
|
||||||
} else {
|
_this.$router.push('/')
|
||||||
ElMessage.error({
|
}, 1500)
|
||||||
dangerouslyUseHTMLString: true,
|
} else {
|
||||||
message: '<strong>用户名</strong> 或 <strong>密码</strong> 错误'
|
ElMessage.error({
|
||||||
})
|
dangerouslyUseHTMLString: true,
|
||||||
}
|
message: '<strong>用户名</strong> 或 <strong>密码</strong> 错误'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,6 +156,7 @@ import {
|
|||||||
} from '@/constants/Common.constants.js'
|
} from '@/constants/Common.constants.js'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import { getUsername, logout } from '@/utils/auth'
|
import { getUsername, logout } from '@/utils/auth'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'MainFrame',
|
name: 'MainFrame',
|
||||||
@@ -187,7 +188,13 @@ export default {
|
|||||||
},
|
},
|
||||||
logout() {
|
logout() {
|
||||||
logout()
|
logout()
|
||||||
this.$router.push({ name: 'Login' })
|
ElMessage.success({
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
message: '<strong>退出登录</strong>'
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$router.push({ name: 'Login' })
|
||||||
|
}, 1500)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import axios, { type AxiosError } from 'axios'
|
import axios, { type AxiosError } from 'axios'
|
||||||
import { getToken, removeToken } from '@/utils/common'
|
import { clearLocalStorage, getToken } from '@/utils/common'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
|
import { TOKEN_HAS_EXPIRED, TOKEN_IS_ILLEGAL, UNAUTHORIZED } from '@/constants/Common.constants'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
baseURL: 'http://localhost:8621',
|
baseURL: 'http://localhost:8621',
|
||||||
@@ -23,17 +25,26 @@ service.interceptors.request.use(
|
|||||||
|
|
||||||
service.interceptors.response.use(
|
service.interceptors.response.use(
|
||||||
(response) => {
|
(response) => {
|
||||||
|
switch (response.data.code) {
|
||||||
|
case UNAUTHORIZED:
|
||||||
|
case TOKEN_IS_ILLEGAL:
|
||||||
|
case TOKEN_HAS_EXPIRED:
|
||||||
|
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||||
|
console.log(`request error: ${response.data.code} - ${response.data.msg}`)
|
||||||
|
clearLocalStorage()
|
||||||
|
ElMessage.error({
|
||||||
|
dangerouslyUseHTMLString: true,
|
||||||
|
message: '<strong>登录已过期</strong>'
|
||||||
|
})
|
||||||
|
setTimeout(function () {
|
||||||
|
void router.push({ name: 'Login' })
|
||||||
|
}, 1500)
|
||||||
|
}
|
||||||
return response
|
return response
|
||||||
},
|
},
|
||||||
async (error) => {
|
async (error) => {
|
||||||
if (error.response != null) {
|
if (error.response != null) {
|
||||||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
/* empty */
|
||||||
console.log(`request error: ${error.response.code} - ${error.response.msg}`)
|
|
||||||
switch (error.response.code) {
|
|
||||||
case 30010:
|
|
||||||
removeToken()
|
|
||||||
await router.push({ name: 'Login' })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return await Promise.reject(error?.response?.data)
|
return await Promise.reject(error?.response?.data)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,19 @@
|
|||||||
import type { Captcha } from './common'
|
import type { Captcha } from './common'
|
||||||
import {
|
import { clearLocalStorage, getCaptcha, getLocalStorage, setLocalStorage } from './common'
|
||||||
getCaptcha,
|
|
||||||
getLocalStorage,
|
|
||||||
getToken,
|
|
||||||
removeLocalStorage,
|
|
||||||
setLocalStorage,
|
|
||||||
setToken
|
|
||||||
} from './common'
|
|
||||||
import { TOKEN_NAME } from '@/constants/Common.constants'
|
import { TOKEN_NAME } from '@/constants/Common.constants'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import request from '@/services'
|
import request from '@/services'
|
||||||
|
|
||||||
let captcha: Captcha
|
let captcha: Captcha
|
||||||
|
|
||||||
async function login(username: string, passwd: string): Promise<boolean> {
|
async function login<T = any>(username: string, passwd: string): Promise<T> {
|
||||||
removeLocalStorage('username')
|
return await request.post('/login', { username, passwd })
|
||||||
await request.post('/login', { username, passwd }).then((res: any) => {
|
|
||||||
const response = res.data
|
|
||||||
if (response.code === 20010) {
|
|
||||||
setToken(response.data.token)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return !_.isEmpty(getToken())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function logout(): void {
|
function logout(): void {
|
||||||
removeLocalStorage(TOKEN_NAME)
|
void request.get('/logout').finally(() => {
|
||||||
removeLocalStorage('username')
|
clearLocalStorage()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLoginStatus(): boolean {
|
function getLoginStatus(): boolean {
|
||||||
|
|||||||
@@ -77,6 +77,10 @@ function removeToken(): void {
|
|||||||
removeLocalStorage(TOKEN_NAME)
|
removeLocalStorage(TOKEN_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clearLocalStorage(): void {
|
||||||
|
localStorage.clear()
|
||||||
|
}
|
||||||
|
|
||||||
function randomInt(start: number, end: number): number {
|
function randomInt(start: number, end: number): number {
|
||||||
if (start > end) {
|
if (start > end) {
|
||||||
const t = start
|
const t = start
|
||||||
@@ -149,5 +153,6 @@ export {
|
|||||||
removeCookie,
|
removeCookie,
|
||||||
removeLocalStorage,
|
removeLocalStorage,
|
||||||
removeToken,
|
removeToken,
|
||||||
|
clearLocalStorage,
|
||||||
getCaptcha
|
getCaptcha
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user