这里需要拦截器、oauth等配合使用 实现单点登录
Step1:先写逻辑接口和实现
public interface TokenService {
/**
* 创建accessToken
* @param userId
* @return
*/
String createToken(String userId);
/**
* 刷新accessToken
* @param accessToken
* @return
*/
String refreshToken(String accessToken);
/**
* 验证accessToken
* @param accessToken
* @return
*/
UserVO validateToken(String accessToken);
/**
* 更新用户信息
* @param user
*/
void updateUserByToken(UserVO user);
}
step2:实现接口中的方法
@Service
public class TokenServiceImpl implements TokenService {
@Resource private RedisService redisService;
@Resource private UserService userService;
@Override
public String createToken(String userId) {
UserVO userVO = userService.getById(userId).of();
//如果redis存在这个token,移除
if(StrUtil.isNotBlank(userVO.getAccessToken())){
redisService.remove(AccessToken.getKey(),userVO.getAccessToken());
}
String accessToken = IdUtil.fastSimpleUUID();
userVO.setAccessToken(accessToken);
redisService.put(AccessToken.getKey(), accessToken, encodeUser(userVO), AccessToken.getExpire());
userService.updateToken(userVO);
return accessToken;
}
@Override
public UserVO validateToken(String accessToken) {
UserVO user = getUser(accessToken);
//更新用户当前的最新信息
userService.updateToken(user);
return user;
}
@Override
public String refreshToken(String accessToken) {
UserVO user = getUser(accessToken);
return this.createToken(user.getUuid());
}
@Override
public void updateUserByToken(UserVO user) {
validToken(user.getAccessToken());
redisService.put(AccessToken.getKey(),user.getAccessToken(), encodeUser(user), AccessToken.getExpire());
}
public UserVO getUser(String accessToken)throws BusinessException {
validToken(accessToken);
UserVO user = decodeUser(accessToken);
validUser(user);
return user;
}
/**
* 校验token信息
* @param accessToken 认证
* @return
* @throws BusinessException
*/
public boolean validToken(String accessToken) throws BusinessException{
if(StrUtil.isBlank(accessToken)){
throw new BusinessException(Login.getCode(),NotLogin.getCode(),NotLogin.getMsg());
}
boolean keyExists = redisService.isKeyExists(AccessToken.getKey(), accessToken);
if(!keyExists) {
throw new BusinessException(Login.getCode(),TokenLose.getCode(), TokenLose.getMsg());
}
return true;
}
/**
* 校验用户信息
* @param user
* @return
* @throws BusinessException
*/
public boolean validUser(UserVO user)throws BusinessException{
if(user == null){
throw new BusinessException(NotRegister.getCode(),NotRegister.getMsg());
}
if (Status.User.Forbid.getStatus() .equals(user.getStatus())){
throw new BusinessException(Login.getCode(),Forbid.getCode(),Forbid.getMsg());
}
return true;
}
/**
* 加密用户信息
* @param user
* @return
*/
public String encodeUser(UserVO user){
String userJson = JSONObject.toJSONString(user);
return Base64.encode(userJson);
}
/**
* 解密用户信息
* @param accessToken
* @return
*/
public UserVO decodeUser(String accessToken){
String userString= (String) redisService.get(AccessToken.getKey(), accessToken);
String userJson = Base64.decodeStr(userString);
return JSONObject.parseObject(userJson,UserVO.class);
}
}
请点击查看拦截器具体代码
最好可以放在BaseController,所有的controller 可以继承他,这样可以取到用户信息
@Controller
public class BaseController {
@Resource
private TokenService tokenService;
public UserVO getUser(){
final String token = RequestUtil.getToken();
return tokenService.validateToken(token);
}
}
到这就完成了,有喜欢的小伙伴们可以点个赞,也可以关注下,里面还有其他干货可以看看。