Spring Gateway、Sa-Token、nacos完成认证/鉴权

Spring Gateway、Sa-Token、nacos完成认证/鉴权_第1张图片

Spring Gateway、Sa-Token、nacos完成认证/鉴权

前言

之前进行鉴权、授权都要写一大堆代码。如果使用像Spring Security这样的框架,又要花好多时间学习,拿过来一用,好多配置项也不知道是干嘛用的,又不想了解。要是不用Spring Security,token的生成、校验、刷新,权限的验证分配,又全要自己写,想想都头大。

Spring Security太重而且配置繁琐。自己实现所有的点必须又要顾及到,更是麻烦。

最近看到一个权限认证框架,真是够简单高效。这里分享一个使用Sa-Token的gateway鉴权demo。

Spring Gateway、Sa-Token、nacos完成认证/鉴权_第2张图片

Sa-Token

需求分析

Spring Gateway、Sa-Token、nacos完成认证/鉴权_第3张图片

结构

Spring Gateway、Sa-Token、nacos完成认证/鉴权_第4张图片

认证

sa-token模块

我们首先编写sa-token模块进行token生成和权限分配。

在sa-token的session模式下生成token非常方便,只需要调用

StpUtil.login(Object id);     
复制代码

就可以为账号生成 Token 凭证与 Session 会话了。

配置信息

server:
  # 端口
  port: 8081
​
spring:
  application:
    name: weishuang-account
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/weishuang_account?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=CONVERT_TO_NULL
    username: root
    password: root
  # redis配置
  redis:
    # Redis数据库索引(默认为0)
    database: 0
    # Redis服务器地址
    host: 127.0.0.1
    # Redis服务器连接端口
    port: 6379
    # Redis服务器连接密码(默认为空)
    # password:
    # 连接超时时间
    timeout: 10s
    lettuce:
      pool:
        # 连接池最大连接数
        max-active: 200
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
        # 连接池中的最大空闲连接
        max-idle: 10
        # 连接池中的最小空闲连接
        min-idle: 0
​
​
############## Sa-Token 配置 (文档: https://sa-token.cc) ##############
sa-token:
  # token名称 (同时也是cookie名称)
  token-name: weishuang-token
  # token有效期,单位s 默认30天, -1代表永不过期
  timeout: 2592000
  # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
  activity-timeout: -1
  # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
  is-concurrent: true
  # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
  is-share: true
  # token风格
  token-style: uuid
  # 是否输出操作日志
  is-log: false
  # token前缀
  token-prefix: Bearer
复制代码

在sa-token的配置中,我使用了token-name来指定token的名称,如果不指定那么就是默认的satoken。

使用token-prefix来指定token的前缀,这样前端在header里传入token的时候就要加上Bearer了(注意有个空格),建议和前端商量一下需不需要这个前缀,如果不使用,直接传token就好了。

现在调用接口时传入的格式就是

weishuang-token = Bearer token123456
复制代码

sa-token的session模式需要redis来存储session,在微服务中,各个服务的session也需要redis来同步。

当然sa-token也支持jwt来生成无状态的token,这样就不需要在服务中引入redis了。本文使用session模式(jwt的刷新token等机制还要自己实现,session的刷新sa-token都帮我们做好了,使用默认的模式更加方便,而且功能更多)

我们来编写一个登录接口

User

@Data
public class User {
​
    /**
     * id
     */
    private String id;
​
    /**
     * 账号
     */
    private String userName;
​
    /**
     * 密码
     */
    private String password;
​
}
复制代码

UserController

@RestController
@RequestMapping("/account/user/")
public class UserController {
​
    @Autowired
    private UserManager userManager;
​
    @PostMapping("doLogin")
    public SaResult doLogin(@RequestBody AccountUserLoginDTO req) {
        userManager.login(req);
​
        return SaResult.ok("登录成功");
    }
}
复制代码

UserManager

@Component
public class UserManagerImpl implements UserManager {
​
    @Autowired
    private UserService userService;
​
    @Override
    public void login(AccountUserLoginDTO req) {
        //生成密码
        String password = PasswordUtil.generatePassword(req.getPassword());
        //调用数据库校验是否存在用户
        User user = userService.getOne(req.getUserName(), password);
        if (user == null) {
            throw new RuntimeException("账号或密码错误");
        }
        
        //为账号生成Token凭证与Session会话
        StpUtil.login(user.getId());
        //为该用户的session存储更多信息
        //这里为了方便直接把user实体存进去了,也包括了密码,自己实现时不建议这样做。
        StpUtil.getSession().set("USER_DATA", user);
    }
​
}
复制代码

UserService

@Service
public class UserService

你可能感兴趣的:(spring,gateway,数据库)