springboot 实现单点登录

这里需要拦截器、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);
    }
}

到这就完成了,有喜欢的小伙伴们可以点个赞,也可以关注下,里面还有其他干货可以看看。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值