diff --git a/im-platform/src/main/java/com/bx/implatform/config/MvcConfig.java b/im-platform/src/main/java/com/bx/implatform/config/MvcConfig.java index 5e84cce..ccf7192 100644 --- a/im-platform/src/main/java/com/bx/implatform/config/MvcConfig.java +++ b/im-platform/src/main/java/com/bx/implatform/config/MvcConfig.java @@ -17,7 +17,7 @@ public class MvcConfig implements WebMvcConfigurer { public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authInterceptor()) .addPathPatterns("/**") - .excludePathPatterns( "/image/upload","/login","/logout","/register", + .excludePathPatterns( "/image/upload","/login","/logout","/register","/refreshToken", "/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**"); } diff --git a/im-platform/src/main/java/com/bx/implatform/contant/Constant.java b/im-platform/src/main/java/com/bx/implatform/contant/Constant.java index fed83f1..4aedad3 100644 --- a/im-platform/src/main/java/com/bx/implatform/contant/Constant.java +++ b/im-platform/src/main/java/com/bx/implatform/contant/Constant.java @@ -9,7 +9,7 @@ public class Constant { // 群聊最大人数 public static final long MAX_GROUP_MEMBER = 500; // accessToken 过期时间(1小时) - public static final Integer ACCESS_TOKEN_EXPIRE = 60 * 60; + public static final Integer ACCESS_TOKEN_EXPIRE = 30 * 60; // refreshToken 过期时间(7天) public static final Integer REFRESH_TOKEN_EXPIRE = 7 * 24 * 60 * 60 ; // accessToken 加密秘钥 diff --git a/im-platform/src/main/java/com/bx/implatform/controller/LoginController.java b/im-platform/src/main/java/com/bx/implatform/controller/LoginController.java index 6637130..4e70554 100644 --- a/im-platform/src/main/java/com/bx/implatform/controller/LoginController.java +++ b/im-platform/src/main/java/com/bx/implatform/controller/LoginController.java @@ -10,10 +10,7 @@ import com.bx.implatform.vo.LoginVO; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestHeader; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -34,7 +31,7 @@ public class LoginController { } - @PostMapping("/refreshToken") + @PutMapping("/refreshToken") @ApiOperation(value = "刷新token",notes="用refreshtoken换取新的token") public Result refreshToken(@RequestHeader("refreshToken")String refreshToken){ LoginVO vo = userService.refreshToken(refreshToken); diff --git a/im-platform/src/main/java/com/bx/implatform/interceptor/AuthInterceptor.java b/im-platform/src/main/java/com/bx/implatform/interceptor/AuthInterceptor.java index d1f275a..3a71fbe 100644 --- a/im-platform/src/main/java/com/bx/implatform/interceptor/AuthInterceptor.java +++ b/im-platform/src/main/java/com/bx/implatform/interceptor/AuthInterceptor.java @@ -24,7 +24,7 @@ public class AuthInterceptor implements HandlerInterceptor { return true; } //从 http 请求头中取出 token - String token = request.getHeader("token"); + String token = request.getHeader("accessToken"); if (token == null) { throw new GlobalException(ResultCode.NO_LOGIN); } diff --git a/im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java b/im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java index d522974..b04aebf 100644 --- a/im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java +++ b/im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java @@ -74,11 +74,11 @@ public class UserServiceImpl extends ServiceImpl implements IU String strJson = JSON.toJSONString(session); String accessToken = JwtUtil.sign(user.getId(),strJson, Constant.ACCESS_TOKEN_EXPIRE,Constant.ACCESS_TOKEN_SECRET); String refreshToken = JwtUtil.sign(user.getId(),strJson, Constant.REFRESH_TOKEN_EXPIRE, REFRESH_TOKEN_SECRET); - LoginVO vo =new LoginVO(); + LoginVO vo = new LoginVO(); vo.setAccessToken(accessToken); vo.setAccessTokenExpiresIn(Constant.ACCESS_TOKEN_EXPIRE); vo.setRefreshToken(refreshToken); - vo.setAccessTokenExpiresIn(Constant.REFRESH_TOKEN_EXPIRE); + vo.setRefreshTokenExpiresIn(Constant.REFRESH_TOKEN_EXPIRE); return vo; } @@ -101,10 +101,10 @@ public class UserServiceImpl extends ServiceImpl implements IU vo.setAccessToken(accessToken); vo.setAccessTokenExpiresIn(Constant.ACCESS_TOKEN_EXPIRE); vo.setRefreshToken(newRefreshToken); - vo.setAccessTokenExpiresIn(Constant.REFRESH_TOKEN_EXPIRE); + vo.setRefreshTokenExpiresIn(Constant.REFRESH_TOKEN_EXPIRE); return vo; }catch (JWTVerificationException e) { - throw new GlobalException(ResultCode.INVALID_TOKEN); + throw new GlobalException("refreshToken已失效"); } } diff --git a/im-ui/src/api/httpRequest.js b/im-ui/src/api/httpRequest.js index 020eab4..7f8f376 100644 --- a/im-ui/src/api/httpRequest.js +++ b/im-ui/src/api/httpRequest.js @@ -1,6 +1,8 @@ import axios from 'axios' import router from '@/router' -import {Message} from 'element-ui' +import { + Message +} from 'element-ui' const http = axios.create({ baseURL: process.env.VUE_APP_BASE_API, @@ -15,9 +17,9 @@ const http = axios.create({ * 请求拦截 */ http.interceptors.request.use(config => { - let token = sessionStorage.getItem("token"); - if (token) { - config.headers.token = sessionStorage.getItem("token"); + let accessToken = sessionStorage.getItem("accessToken"); + if (accessToken) { + config.headers.accessToken = encodeURIComponent(accessToken); } return config }, error => { @@ -27,9 +29,32 @@ http.interceptors.request.use(config => { /** * 响应拦截 */ -http.interceptors.response.use(response => { +http.interceptors.response.use(async response => { if (response.data.code == 200) { return response.data.data; + } else if (response.data.code == 400) { + router.replace("/login"); + } else if (response.data.code == 401) { + console.log("token失效,尝试重新获取") + let refreshToken = sessionStorage.getItem("refreshToken"); + if (!refreshToken) { + router.replace("/login"); + } + // 发送请求, 进行刷新token操作, 获取新的token + const data = await http({ + method: 'put', + url: '/refreshToken', + headers: { + refreshToken: refreshToken + } + }) + // 保存token + sessionStorage.setItem("accessToken", data.accessToken); + sessionStorage.setItem("refreshToken", data.refreshToken); + // 这里需要把headers清掉,否则请求时会报错,原因暂不详... + response.config.headers=undefined; + // 重新发送刚才的请求 + return http(response.config) } else { Message({ message: response.data.message, @@ -37,10 +62,6 @@ http.interceptors.response.use(response => { duration: 1500, customClass: 'element-error-message-zindex' }) - - if (response.data.code == 401) { - router.replace("/login"); - } return Promise.reject(response.data) } }, error => { diff --git a/im-ui/src/view/Login.vue b/im-ui/src/view/Login.vue index 0ef70cb..620bb49 100644 --- a/im-ui/src/view/Login.vue +++ b/im-ui/src/view/Login.vue @@ -67,11 +67,12 @@ data: this.loginForm }) .then((data) => { - // 保存密码到cookie(方便但不安全) + // 保存密码到cookie(不安全) this.setCookie('username',this.loginForm.userName); this.setCookie('password',this.loginForm.password); // 保存token - sessionStorage.setItem("token",data.accessToken); + sessionStorage.setItem("accessToken",data.accessToken); + sessionStorage.setItem("refreshToken",data.refreshToken); this.$message.success("登陆成功"); this.$router.push("/home/chat"); })