5.9 KiB
5.9 KiB
在上小节 中,我们已经实现了网关透传用户 ID 给下游服务,下游服务知道了请求对应的用户 ID,才能方便的处理相关业务,比如用户退出登录。本小节中,就来把用户退出登录接口开发完成。
接口定义
接口地址
POST /user/logout
入参
无入参。只需请求头中携带上 Token 即可。
出参
{
"success": true, // true 表示退出登录成功
"message": null,
"errorCode": null,
"data": null
}
编写业务逻辑
之前测试权限校验的时候,退出登录接口已经在认证服务中定义好了,接下来,仅需补充对应逻辑即可。
service 业务层
编辑 UserService 业务接口,声明一个退出登录方法,入参为请求头透传过来的用户 ID, 代码如下:
package com.quanxiaoha.xiaohashu.auth.service;
import com.quanxiaoha.framework.common.response.Response;
import com.quanxiaoha.xiaohashu.auth.model.vo.user.UserLoginReqVO;
public interface UserService {
// 省略...
/**
* 退出登录
* @return
*/
Response<?> logout(Long userId);
}
接着,编辑其实现类 UserServiceImpl,实现上述方法,并添加逻辑代码如下:
package com.quanxiaoha.xiaohashu.auth.service.impl;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.quanxiaoha.framework.common.enums.DeletedEnum;
import com.quanxiaoha.framework.common.enums.StatusEnum;
import com.quanxiaoha.framework.common.exception.BizException;
import com.quanxiaoha.framework.common.response.Response;
import com.quanxiaoha.framework.common.util.JsonUtils;
import com.quanxiaoha.xiaohashu.auth.constant.RedisKeyConstants;
import com.quanxiaoha.xiaohashu.auth.constant.RoleConstants;
import com.quanxiaoha.xiaohashu.auth.domain.dataobject.PermissionDO;
import com.quanxiaoha.xiaohashu.auth.domain.dataobject.RoleDO;
import com.quanxiaoha.xiaohashu.auth.domain.dataobject.UserDO;
import com.quanxiaoha.xiaohashu.auth.domain.dataobject.UserRoleDO;
import com.quanxiaoha.xiaohashu.auth.domain.mapper.RoleDOMapper;
import com.quanxiaoha.xiaohashu.auth.domain.mapper.UserDOMapper;
import com.quanxiaoha.xiaohashu.auth.domain.mapper.UserRoleDOMapper;
import com.quanxiaoha.xiaohashu.auth.enums.LoginTypeEnum;
import com.quanxiaoha.xiaohashu.auth.enums.ResponseCodeEnum;
import com.quanxiaoha.xiaohashu.auth.model.vo.user.UserLoginReqVO;
import com.quanxiaoha.xiaohashu.auth.service.UserService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionTemplate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@Service
@Slf4j
public class UserServiceImpl implements UserService {
// 省略...
/**
* 退出登录
*
* @param userId
* @return
*/
@Override
public Response<?> logout(Long userId) {
// 退出登录 (指定用户 ID)
StpUtil.logout(userId);
return Response.success();
}
// 省略...
}
逻辑很简单,通过 SaToken 的工具类方法
StpUtil.logout(userId);,传入想要退出登录的用户 ID 即可。
Controller 层
最后,编辑 UserController 控制器,修改代码如下:
package com.quanxiaoha.xiaohashu.auth.controller;
import com.quanxiaoha.framework.biz.operationlog.aspect.ApiOperationLog;
import com.quanxiaoha.framework.common.response.Response;
import com.quanxiaoha.xiaohashu.auth.model.vo.user.UserLoginReqVO;
import com.quanxiaoha.xiaohashu.auth.service.UserService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* @author: 犬小哈
* @date: 2024/5/29 15:32
* @version: v1.0.0
* @description: TODO
**/
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@Resource
private UserService userService;
// 省略...
@PostMapping("/logout")
@ApiOperationLog(description = "账号登出")
public Response<?> logout(@RequestHeader("userId") String userId) {
return userService.logout(Long.valueOf(userId));
}
}
测试一波
代码编写完毕后,重启一下认证服务。在测试登出接口之前,观察 Redis 中存储的会话信息,先确认一下等会要退出登录的 Token 是否存在,存在则说明对应的用户处于登录状态,如下图所示:
打开 Apipost 工具, 测试一波退出登录接口,如下所示:
响参提示操作成功,再来观察一下 Redis 中该 Token 是否还在,如下图所示,可以看到之前存在的 Token ,已经被删除了,会话信息也被删除了:
为了再次验证一下,用刚才的 Token 令牌,再次调用退出登录接口,响参也提示当前 Token 已经无效了:
至此,用户退出登录接口就开发完成啦,是不是很简单~