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_FILE_SIZE = 10*1024*1024;
// 群聊最大人数 // 群聊最大人数
public static final long MAX_GROUP_MEMBER = 500; 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; package com.bx.implatform.controller;
import com.bx.implatform.enums.ResultCode;
import com.bx.implatform.result.Result; import com.bx.implatform.result.Result;
import com.bx.implatform.result.ResultUtils; import com.bx.implatform.result.ResultUtils;
import com.bx.implatform.service.IUserService; 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.LoginVO;
import com.bx.implatform.vo.RegisterVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; 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.RestController;
import javax.validation.Valid; import javax.validation.Valid;
@ -27,16 +28,24 @@ public class LoginController {
@PostMapping("/login") @PostMapping("/login")
@ApiOperation(value = "用户注册",notes="用户注册") @ApiOperation(value = "用户注册",notes="用户注册")
public Result register(@Valid @RequestBody LoginVO vo){ public Result register(@Valid @RequestBody LoginDTO dto){
String token = userService.login(vo); LoginVO vo = userService.login(dto);
return ResultUtils.success(token,ResultCode.SUCCESS.getMsg()); 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") @PostMapping("/register")
@ApiOperation(value = "用户注册",notes="用户注册") @ApiOperation(value = "用户注册",notes="用户注册")
public Result register(@Valid @RequestBody RegisterVO vo){ public Result register(@Valid @RequestBody RegisterDTO dto){
userService.register(vo); userService.register(dto);
return ResultUtils.success(); 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.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
@ -9,7 +9,7 @@ import javax.validation.constraints.NotEmpty;
@Data @Data
@ApiModel("用户注册VO") @ApiModel("用户注册VO")
public class RegisterVO { public class RegisterDTO {
@Length(max = 64,message = "用户名不能大于64字符") @Length(max = 64,message = "用户名不能大于64字符")
@NotEmpty(message="用户名不可为空") @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 { public enum ResultCode {
SUCCESS(200,"成功"), SUCCESS(200,"成功"),
LOGIN_ERROR(400,"登录异常"), NO_LOGIN(400,"登录"),
NO_LOGIN(401,"未登录"), INVALID_TOKEN(401,"token已失效"),
PROGRAM_ERROR(500,"系统繁忙,请稍后再试"), PROGRAM_ERROR(500,"系统繁忙,请稍后再试"),
PASSWOR_ERROR(10001,"密码不正确"), PASSWOR_ERROR(10001,"密码不正确"),
USERNAME_ALREADY_REGISTER(10003,"该用户名已注册"), 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.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.enums.ResultCode;
import com.bx.implatform.exception.GlobalException; import com.bx.implatform.exception.GlobalException;
import com.bx.implatform.session.UserSession; import com.bx.implatform.session.UserSession;
@ -26,8 +28,13 @@ public class AuthInterceptor implements HandlerInterceptor {
if (token == null) { if (token == null) {
throw new GlobalException(ResultCode.NO_LOGIN); throw new GlobalException(ResultCode.NO_LOGIN);
} }
//验证 token try{
JwtUtil.checkSign(token); //验证 token
JwtUtil.checkSign(token, Constant.ACCESS_TOKEN_SECRET);
}catch (
JWTVerificationException e) {
throw new GlobalException(ResultCode.INVALID_TOKEN);
}
// 存放session // 存放session
String strJson = JwtUtil.getInfo(token); String strJson = JwtUtil.getInfo(token);
UserSession userSession = JSON.parseObject(strJson,UserSession.class); 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.baomidou.mybatisplus.extension.service.IService;
import com.bx.implatform.entity.User; 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.LoginVO;
import com.bx.implatform.vo.RegisterVO;
import com.bx.implatform.vo.UserVO; import com.bx.implatform.vo.UserVO;
import java.util.List; import java.util.List;
@ -11,9 +12,11 @@ import java.util.List;
public interface IUserService extends IService<User> { 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); 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; package com.bx.implatform.service.impl;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bx.imcommon.contant.RedisKey; import com.bx.imcommon.contant.RedisKey;
import com.bx.implatform.contant.Constant;
import com.bx.implatform.entity.Friend; import com.bx.implatform.entity.Friend;
import com.bx.implatform.entity.GroupMember; import com.bx.implatform.entity.GroupMember;
import com.bx.implatform.entity.User; 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.session.UserSession;
import com.bx.implatform.util.BeanUtils; import com.bx.implatform.util.BeanUtils;
import com.bx.implatform.util.JwtUtil; 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.LoginVO;
import com.bx.implatform.vo.RegisterVO;
import com.bx.implatform.vo.UserVO; import com.bx.implatform.vo.UserVO;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -31,6 +34,8 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.bx.implatform.contant.Constant.REFRESH_TOKEN_SECRET;
@Slf4j @Slf4j
@Service @Service
@ -51,42 +56,74 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IU
/** /**
* 用户登录 * 用户登录
* *
* @param vo 注册vo * @param dto 登录dto
* @return * @return
*/ */
@Override @Override
public String login(LoginVO vo) { public LoginVO login(LoginDTO dto) {
User user = findUserByName(vo.getUserName()); User user = findUserByName(dto.getUserName());
if(null == user){ if(null == user){
throw new GlobalException(ResultCode.PROGRAM_ERROR,"用户不存在"); 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); throw new GlobalException(ResultCode.PASSWOR_ERROR);
} }
// 生成token // 生成token
UserSession session = BeanUtils.copyProperties(user,UserSession.class); UserSession session = BeanUtils.copyProperties(user,UserSession.class);
String strJson = JSON.toJSONString(session); String strJson = JSON.toJSONString(session);
String token = JwtUtil.sign(user.getId(),strJson); String accessToken = JwtUtil.sign(user.getId(),strJson, Constant.ACCESS_TOKEN_EXPIRE,Constant.ACCESS_TOKEN_SECRET);
return token; 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 * @return
*/ */
@Override @Override
public void register(RegisterVO vo) { public void register(RegisterDTO dto) {
User user = findUserByName(vo.getUserName()); User user = findUserByName(dto.getUserName());
if(null != user){ if(null != user){
throw new GlobalException(ResultCode.USERNAME_ALREADY_REGISTER); 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())); user.setPassword(passwordEncoder.encode(user.getPassword()));
this.save(user); 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.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException; 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.Date;
import java.util.Map;
public class JwtUtil {
/**
* 过期5分钟
* */
private static final long EXPIRE_TIME = 30 * 60 * 1000;
/** public class JwtUtil {
* jwt密钥
* */
private static final String SECRET = "MIIBIjANBgkq";
/** /**
* 生成jwt字符串30分钟后过期 JWT(json web token) * 生成jwt字符串30分钟后过期 JWT(json web token)
* @param userId * @param userId
* @param info * @param info
* @param expireIn
* @param secret
* @return * @return
* */ * */
public static String sign(Long userId, String info) { public static String sign(Long userId, String info,long expireIn,String secret) {
try { try {
Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME); Date date = new Date(System.currentTimeMillis() + expireIn*1000);
Algorithm algorithm = Algorithm.HMAC256(SECRET); Algorithm algorithm = Algorithm.HMAC256(secret);
return JWT.create() return JWT.create()
//将userId保存到token里面 //将userId保存到token里面
.withAudience(userId.toString()) .withAudience(userId.toString())
@ -77,18 +66,15 @@ public class JwtUtil {
/** /**
* 校验token * 校验token
* @param token * @param token
* @param secret
* @return * @return
* */ * */
public static boolean checkSign(String token) { public static boolean checkSign(String token,String secret) {
try { Algorithm algorithm = Algorithm.HMAC256(secret);
Algorithm algorithm = Algorithm.HMAC256(SECRET);
JWTVerifier verifier = JWT.require(algorithm) JWTVerifier verifier = JWT.require(algorithm)
//.withClaim("username, username) //.withClaim("username, username)
.build(); .build();
verifier.verify(token); verifier.verify(token);
return true; 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.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
@Data @Data
@ApiModel("用户登录VO") @ApiModel("用户登录VO")
public class LoginVO { public class LoginVO {
//@NotEmpty(message="用户名不可为空") @ApiModelProperty(value = "每次请求都必须在header中携带accessToken")
@ApiModelProperty(value = "用户名") private String accessToken;
private String userName;
@ApiModelProperty(value = "accessToken过期时间(秒)")
private Integer accessTokenExpiresIn;
// @NotEmpty(message="用户密码不可为空") @ApiModelProperty(value = "accessToken过期后,通过refreshToken换取新的token")
@ApiModelProperty(value = "用户密码") private String refreshToken;
private String password;
@ApiModelProperty(value = "refreshToken过期时间(秒)")
private Integer refreshTokenExpiresIn;
} }

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

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

Loading…
Cancel
Save