Browse Source

刷新token(后端)

master
xie.bx 3 years ago
parent
commit
76b8fe25c3
  1. 8
      im-platform/src/main/java/com/bx/implatform/contant/Constant.java
  2. 23
      im-platform/src/main/java/com/bx/implatform/controller/LoginController.java
  3. 22
      im-platform/src/main/java/com/bx/implatform/dto/LoginDTO.java
  4. 4
      im-platform/src/main/java/com/bx/implatform/dto/RegisterDTO.java
  5. 4
      im-platform/src/main/java/com/bx/implatform/enums/ResultCode.java
  6. 11
      im-platform/src/main/java/com/bx/implatform/interceptor/AuthInterceptor.java
  7. 9
      im-platform/src/main/java/com/bx/implatform/service/IUserService.java
  8. 61
      im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java
  9. 32
      im-platform/src/main/java/com/bx/implatform/util/JwtUtil.java
  10. 18
      im-platform/src/main/java/com/bx/implatform/vo/LoginVO.java
  11. 4
      im-ui/src/view/Login.vue

8
im-platform/src/main/java/com/bx/implatform/contant/Constant.java

@ -8,5 +8,13 @@ public class Constant {
public static final long MAX_FILE_SIZE = 10*1024*1024;
// 群聊最大人数
public static final long MAX_GROUP_MEMBER = 500;
// accessToken 过期时间(1小时)
public static final Integer ACCESS_TOKEN_EXPIRE = 60 * 60;
// refreshToken 过期时间(7天)
public static final Integer REFRESH_TOKEN_EXPIRE = 7 * 24 * 60 * 60 ;
// accessToken 加密秘钥
public static final String ACCESS_TOKEN_SECRET = "MIIBIjANBgkq";
// refreshToken 加密秘钥
public static final String REFRESH_TOKEN_SECRET = "IKDiqVmn0VFU";
}

23
im-platform/src/main/java/com/bx/implatform/controller/LoginController.java

@ -1,17 +1,18 @@
package com.bx.implatform.controller;
import com.bx.implatform.enums.ResultCode;
import com.bx.implatform.result.Result;
import com.bx.implatform.result.ResultUtils;
import com.bx.implatform.service.IUserService;
import com.bx.implatform.dto.LoginDTO;
import com.bx.implatform.dto.RegisterDTO;
import com.bx.implatform.vo.LoginVO;
import com.bx.implatform.vo.RegisterVO;
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 javax.validation.Valid;
@ -27,16 +28,24 @@ public class LoginController {
@PostMapping("/login")
@ApiOperation(value = "用户注册",notes="用户注册")
public Result register(@Valid @RequestBody LoginVO vo){
String token = userService.login(vo);
return ResultUtils.success(token,ResultCode.SUCCESS.getMsg());
public Result register(@Valid @RequestBody LoginDTO dto){
LoginVO vo = userService.login(dto);
return ResultUtils.success(vo);
}
@PostMapping("/refreshToken")
@ApiOperation(value = "刷新token",notes="用refreshtoken换取新的token")
public Result refreshToken(@RequestHeader("refreshToken")String refreshToken){
LoginVO vo = userService.refreshToken(refreshToken);
return ResultUtils.success(vo);
}
@PostMapping("/register")
@ApiOperation(value = "用户注册",notes="用户注册")
public Result register(@Valid @RequestBody RegisterVO vo){
userService.register(vo);
public Result register(@Valid @RequestBody RegisterDTO dto){
userService.register(dto);
return ResultUtils.success();
}
}

22
im-platform/src/main/java/com/bx/implatform/dto/LoginDTO.java

@ -0,0 +1,22 @@
package com.bx.implatform.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
@Data
@ApiModel("用户登录VO")
public class LoginDTO {
//@NotEmpty(message="用户名不可为空")
@ApiModelProperty(value = "用户名")
private String userName;
// @NotEmpty(message="用户密码不可为空")
@ApiModelProperty(value = "用户密码")
private String password;
}

4
im-platform/src/main/java/com/bx/implatform/vo/RegisterVO.java → im-platform/src/main/java/com/bx/implatform/dto/RegisterDTO.java

@ -1,4 +1,4 @@
package com.bx.implatform.vo;
package com.bx.implatform.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ -9,7 +9,7 @@ import javax.validation.constraints.NotEmpty;
@Data
@ApiModel("用户注册VO")
public class RegisterVO {
public class RegisterDTO {
@Length(max = 64,message = "用户名不能大于64字符")
@NotEmpty(message="用户名不可为空")

4
im-platform/src/main/java/com/bx/implatform/enums/ResultCode.java

@ -9,8 +9,8 @@ package com.bx.implatform.enums;
**/
public enum ResultCode {
SUCCESS(200,"成功"),
LOGIN_ERROR(400,"登录异常"),
NO_LOGIN(401,"未登录"),
NO_LOGIN(400,"登录"),
INVALID_TOKEN(401,"token已失效"),
PROGRAM_ERROR(500,"系统繁忙,请稍后再试"),
PASSWOR_ERROR(10001,"密码不正确"),
USERNAME_ALREADY_REGISTER(10003,"该用户名已注册"),

11
im-platform/src/main/java/com/bx/implatform/interceptor/AuthInterceptor.java

@ -2,6 +2,8 @@ package com.bx.implatform.interceptor;
import com.alibaba.fastjson.JSON;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.bx.implatform.contant.Constant;
import com.bx.implatform.enums.ResultCode;
import com.bx.implatform.exception.GlobalException;
import com.bx.implatform.session.UserSession;
@ -26,8 +28,13 @@ public class AuthInterceptor implements HandlerInterceptor {
if (token == null) {
throw new GlobalException(ResultCode.NO_LOGIN);
}
//验证 token
JwtUtil.checkSign(token);
try{
//验证 token
JwtUtil.checkSign(token, Constant.ACCESS_TOKEN_SECRET);
}catch (
JWTVerificationException e) {
throw new GlobalException(ResultCode.INVALID_TOKEN);
}
// 存放session
String strJson = JwtUtil.getInfo(token);
UserSession userSession = JSON.parseObject(strJson,UserSession.class);

9
im-platform/src/main/java/com/bx/implatform/service/IUserService.java

@ -2,8 +2,9 @@ package com.bx.implatform.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.bx.implatform.entity.User;
import com.bx.implatform.dto.LoginDTO;
import com.bx.implatform.dto.RegisterDTO;
import com.bx.implatform.vo.LoginVO;
import com.bx.implatform.vo.RegisterVO;
import com.bx.implatform.vo.UserVO;
import java.util.List;
@ -11,9 +12,11 @@ import java.util.List;
public interface IUserService extends IService<User> {
String login(LoginVO vo);
LoginVO login(LoginDTO dto);
void register(RegisterVO vo);
LoginVO refreshToken(String refreshToken);
void register(RegisterDTO dto);
User findUserByName(String username);

61
im-platform/src/main/java/com/bx/implatform/service/impl/UserServiceImpl.java

@ -1,9 +1,11 @@
package com.bx.implatform.service.impl;
import com.alibaba.fastjson.JSON;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bx.imcommon.contant.RedisKey;
import com.bx.implatform.contant.Constant;
import com.bx.implatform.entity.Friend;
import com.bx.implatform.entity.GroupMember;
import com.bx.implatform.entity.User;
@ -17,8 +19,9 @@ import com.bx.implatform.session.SessionContext;
import com.bx.implatform.session.UserSession;
import com.bx.implatform.util.BeanUtils;
import com.bx.implatform.util.JwtUtil;
import com.bx.implatform.dto.LoginDTO;
import com.bx.implatform.dto.RegisterDTO;
import com.bx.implatform.vo.LoginVO;
import com.bx.implatform.vo.RegisterVO;
import com.bx.implatform.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -31,6 +34,8 @@ import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
import static com.bx.implatform.contant.Constant.REFRESH_TOKEN_SECRET;
@Slf4j
@Service
@ -51,42 +56,74 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
/**
* 用户登录
*
* @param vo 注册vo
* @param dto 登录dto
* @return
*/
@Override
public String login(LoginVO vo) {
User user = findUserByName(vo.getUserName());
public LoginVO login(LoginDTO dto) {
User user = findUserByName(dto.getUserName());
if(null == user){
throw new GlobalException(ResultCode.PROGRAM_ERROR,"用户不存在");
}
if(!passwordEncoder.matches(vo.getPassword(),user.getPassword())){
if(!passwordEncoder.matches(dto.getPassword(),user.getPassword())){
throw new GlobalException(ResultCode.PASSWOR_ERROR);
}
// 生成token
UserSession session = BeanUtils.copyProperties(user,UserSession.class);
String strJson = JSON.toJSONString(session);
String token = JwtUtil.sign(user.getId(),strJson);
return token;
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();
vo.setAccessToken(accessToken);
vo.setAccessTokenExpiresIn(Constant.ACCESS_TOKEN_EXPIRE);
vo.setRefreshToken(refreshToken);
vo.setAccessTokenExpiresIn(Constant.REFRESH_TOKEN_EXPIRE);
return vo;
}
/**
* 用refreshToken换取新 token
*
* @param refreshToken
* @return
*/
@Override
public LoginVO refreshToken(String refreshToken) {
try{
//验证 token
JwtUtil.checkSign(refreshToken, REFRESH_TOKEN_SECRET);
String strJson = JwtUtil.getInfo(refreshToken);
Long userId = JwtUtil.getUserId(refreshToken);
String accessToken = JwtUtil.sign(userId,strJson, Constant.ACCESS_TOKEN_EXPIRE,Constant.ACCESS_TOKEN_SECRET);
String newRefreshToken = JwtUtil.sign(userId,strJson, Constant.REFRESH_TOKEN_EXPIRE, REFRESH_TOKEN_SECRET);
LoginVO vo =new LoginVO();
vo.setAccessToken(accessToken);
vo.setAccessTokenExpiresIn(Constant.ACCESS_TOKEN_EXPIRE);
vo.setRefreshToken(newRefreshToken);
vo.setAccessTokenExpiresIn(Constant.REFRESH_TOKEN_EXPIRE);
return vo;
}catch (JWTVerificationException e) {
throw new GlobalException(ResultCode.INVALID_TOKEN);
}
}
/**
* 用户注册
*
* @param vo 注册vo
* @param dto 注册dto
* @return
*/
@Override
public void register(RegisterVO vo) {
User user = findUserByName(vo.getUserName());
public void register(RegisterDTO dto) {
User user = findUserByName(dto.getUserName());
if(null != user){
throw new GlobalException(ResultCode.USERNAME_ALREADY_REGISTER);
}
user = BeanUtils.copyProperties(vo,User.class);
user = BeanUtils.copyProperties(dto,User.class);
user.setPassword(passwordEncoder.encode(user.getPassword()));
this.save(user);
log.info("注册用户,用户id:{},用户名:{},昵称:{}",user.getId(),vo.getUserName(),vo.getNickName());
log.info("注册用户,用户id:{},用户名:{},昵称:{}",user.getId(),dto.getUserName(),dto.getNickName());
}
/**

32
im-platform/src/main/java/com/bx/implatform/util/JwtUtil.java

@ -4,34 +4,23 @@ import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.bx.implatform.exception.GlobalException;
;
import java.util.Date;
import java.util.Map;
public class JwtUtil {
/**
* 过期5分钟
* */
private static final long EXPIRE_TIME = 30 * 60 * 1000;
/**
* jwt密钥
* */
private static final String SECRET = "MIIBIjANBgkq";
public class JwtUtil {
/**
* 生成jwt字符串30分钟后过期 JWT(json web token)
* @param userId
* @param info
* @param expireIn
* @param secret
* @return
* */
public static String sign(Long userId, String info) {
public static String sign(Long userId, String info,long expireIn,String secret) {
try {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
Algorithm algorithm = Algorithm.HMAC256(SECRET);
Date date = new Date(System.currentTimeMillis() + expireIn*1000);
Algorithm algorithm = Algorithm.HMAC256(secret);
return JWT.create()
//将userId保存到token里面
.withAudience(userId.toString())
@ -77,18 +66,15 @@ public class JwtUtil {
/**
* 校验token
* @param token
* @param secret
* @return
* */
public static boolean checkSign(String token) {
try {
Algorithm algorithm = Algorithm.HMAC256(SECRET);
public static boolean checkSign(String token,String secret) {
Algorithm algorithm = Algorithm.HMAC256(secret);
JWTVerifier verifier = JWT.require(algorithm)
//.withClaim("username, username)
.build();
verifier.verify(token);
return true;
}catch (JWTVerificationException e) {
throw new GlobalException("token 无效,请重新获取");
}
}
}

18
im-platform/src/main/java/com/bx/implatform/vo/LoginVO.java

@ -3,20 +3,20 @@ package com.bx.implatform.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
@Data
@ApiModel("用户登录VO")
public class LoginVO {
//@NotEmpty(message="用户名不可为空")
@ApiModelProperty(value = "用户名")
private String userName;
@ApiModelProperty(value = "每次请求都必须在header中携带accessToken")
private String accessToken;
@ApiModelProperty(value = "accessToken过期时间(秒)")
private Integer accessTokenExpiresIn;
// @NotEmpty(message="用户密码不可为空")
@ApiModelProperty(value = "用户密码")
private String password;
@ApiModelProperty(value = "accessToken过期后,通过refreshToken换取新的token")
private String refreshToken;
@ApiModelProperty(value = "refreshToken过期时间(秒)")
private Integer refreshTokenExpiresIn;
}

4
im-ui/src/view/Login.vue

@ -66,12 +66,12 @@
method: 'post',
data: this.loginForm
})
.then((token) => {
.then((data) => {
// cookie(便)
this.setCookie('username',this.loginForm.userName);
this.setCookie('password',this.loginForm.password);
// token
sessionStorage.setItem("token",token);
sessionStorage.setItem("token",data.accessToken);
this.$message.success("登陆成功");
this.$router.push("/home/chat");
})

Loading…
Cancel
Save