【架构师成长之路】3-零基础搭建单体项目-集成sa-token

3.集成sa-token

Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、Session会话、单点登录、OAuth2.0、微服务网关鉴权 等一系列权限相关问题。

<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
        <dependency>
            <groupId>cn.dev33</groupId>
            <artifactId>sa-token-spring-boot-starter</artifactId>
            <version>${sa.token.version}</version>
        </dependency>

        <!--将satoken持久化到redis中-->
        <dependency>
            <groupId>cn.dev33</groupId>
            <artifactId>sa-token-dao-redis-jackson</artifactId>
            <version>${sa.token.version}</version>
        </dependency>
 <!--工具包-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
        </dependency>
 <!--redis-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>${jedis.version}</version>
        </dependency>
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>${redission.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.redisson</groupId>
                    <artifactId>redisson-spring-data-24</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-data-21</artifactId>
            <version>${redission.version}</version>
        </dependency>

新增一个公共返回对象类 Result.java

package com.yy.youbimanage.pojo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

/**
 * @author chase
 * @apiNote
 * @date 2021-08-16 15:18:47
 */
@Data
public class Result<T> implements Serializable {

    
    private Integer code;
    
    private String msg;
   
    private T data;

    public Result ok() {
        this.msg = Response.SUCCESS.getMsg();
        this.code = Response.SUCCESS.getCode();
        return this;
    }

    public Result ok(String msg) {
        this.msg = msg;
        this.code = Response.SUCCESS.getCode();
        return this;
    }

    public Result ok(Response response) {
        this.msg = response.getMsg();
        this.code = response.getCode();
        return this;
    }

    public Result ok(T data) {
        this.msg = Response.SUCCESS.getMsg();
        this.code = Response.SUCCESS.getCode();
        this.data = data;
        return this;
    }

    public Result fail() {
        this.msg = Response.ERROR.getMsg();
        this.code = Response.ERROR.getCode();
        return this;
    }

    public Result fail(String msg) {
        this.code = Response.ERROR.getCode();
        this.msg = msg;
        return this;
    }

    public Result fail(Response response) {
        this.msg = response.getMsg();
        this.code = response.getCode();
        return this;
    }

    public Result fail(String msg, Integer code) {
        this.code = code;
        this.msg = msg;
        return this;
    }

    public enum Response {
        SUCCESS(200, "请求成功"),
        BAD_REQUEST(400, "非法请求"),
        UNAUTHORIZED(401, "尚未登录"),
        FORBIDDEN(403, "权限不足"),
        ERROR(500, "请求失败"),
        USER_ISCOMMENT(10001, "用户已经被禁言");

        private Integer code;
        private String msg;

        Response(Integer code, String msg) {
            this.code = code;
            this.msg = msg;
        }

        public Integer getCode() {
            return code;
        }

        public String getMsg() {
            return msg;
        }

    }

}

新增一个sa-token配置类 SaTokenConfigure.java

package com.chase.frame.config;

import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
import cn.dev33.satoken.interceptor.SaRouteInterceptor;
import cn.hutool.extra.servlet.ServletUtil;
import com.chase.frame.base.Result;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.support.AsyncHandlerMethodReturnValueHandler;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
    @Autowired
    private ObjectMapper objectMapper;

    // 注册拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册Sa-Token的路由拦截器
        registry.addInterceptor(new SaRouteInterceptor())
                .addPathPatterns("/manage/**")
                .excludePathPatterns("/manage/user/login", "/manage/user/logout", "/doc.html");
        registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
    }

    @Override
    public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {
        handlers.add(new ResultHandlerMethodReturnValueHandler(objectMapper));
    }

    public static class ResultHandlerMethodReturnValueHandler implements HandlerMethodReturnValueHandler, AsyncHandlerMethodReturnValueHandler {

        private ObjectMapper objectMapper;

        public ResultHandlerMethodReturnValueHandler(ObjectMapper objectMapper) {
            this.objectMapper = objectMapper;
        }

        @Override
        public boolean isAsyncReturnValue(Object o, MethodParameter methodParameter) {
            return o instanceof Result;
        }

        @Override
        public boolean supportsReturnType(MethodParameter methodParameter) {
            return methodParameter.getMethod().getReturnType().getSimpleName().equals("Result");
        }

        @Override
        public void handleReturnValue(Object o, MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest) throws Exception {
            ServletWebRequest servletWebRequest = (ServletWebRequest) nativeWebRequest;
            HttpServletResponse response = servletWebRequest.getResponse();
            if (o instanceof Result) {
                Result result = (Result) o;
                if (result.getCode() == 400) {
                    response.setStatus(400);
                } else if (result.getCode() == 401) {
                    response.setStatus(401);
                } else if (result.getCode() == 403) {
                    response.setStatus(403);
                } else if (result.getCode() == 500) {
                    response.setStatus(500);
                } else {
                    response.setStatus(200);
                }
                try {
                    ServletUtil.write(response, objectMapper.writeValueAsString(result), "application/json;charset=utf-8");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return;
            }
        }
    }
}


xml配置satoken 集成redis

# Sa-Token配置
sa-token:
  # token名称 (同时也是cookie名称)
  token-name: token
  # token有效期,单位s 默认30, -1代表永不过期
  timeout: -1
  # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
  activity-timeout: -1
  # 是否允许同一账号并发登录 (true时允许一起登录,false时新登录挤掉旧登录)
  is-concurrent: true
  # 在多人登录同一账号时,是否共用一个token (true时所有登录共用一个token,false时每次登录新建一个token)
  is-share: true
  # token风格
  token-style: uuid
  # 是否输出操作日志
  is-log: true
  token-session-check-login: true

spring:
  redis:
      host: 192.168.1.250
      port: 6379
      database: 0
      password: 123456
      lettuce:
        pool:
          min-idle: 1
          max-active: 3
          max-idle: 2
          max-wait: -1ms
          time-between-eviction-runs: 100000

写一个测试方法
【架构师成长之路】3-零基础搭建单体项目-集成sa-token_第1张图片

测试结果获得token 说明引入satoken成功
【架构师成长之路】3-零基础搭建单体项目-集成sa-token_第2张图片

StpUtil.login(10001);    // 标记当前会话登录的账号id
StpUtil.getLoginId();    // 获取当前会话登录的账号id
StpUtil.isLogin();    // 获取当前会话是否已经登录, 返回true或false
StpUtil.logout();    // 当前会话注销登录
StpUtil.kickout(10001);    // 将账号为10001的会话踢下线
StpUtil.hasRole("super-admin");    // 查询当前账号是否含有指定角色标识, 返回true或false
StpUtil.hasPermission("user:add");    // 查询当前账号是否含有指定权限, 返回true或false
StpUtil.getSession();    // 获取当前账号id的Session
StpUtil.getSessionByLoginId(10001);    // 获取账号id为10001的Session
StpUtil.getTokenValueByLoginId(10001);    // 获取账号id为10001的token令牌值
StpUtil.login(10001, "PC");    // 指定设备标识登录,常用于“同端互斥登录”
StpUtil.kickout(10001, "PC");    // 指定账号指定设备标识踢下线 (不同端不受影响)
StpUtil.openSafe(120);    // 在当前会话开启二级认证,有效期为120秒 
StpUtil.checkSafe();    // 校验当前会话是否处于二级认证有效期内,校验失败会抛出异常 
StpUtil.switchTo(10044);    // 将当前会话身份临时切换为其它账号 

Sa-Token 功能一览

登录认证 —— 单端登录、多端登录、同端互斥登录、七天内免登录
权限认证 —— 权限认证、角色认证、会话二级认证
Session会话 —— 全端共享Session、单端独享Session、自定义Session
踢人下线 —— 根据账号id踢人下线、根据Token值踢人下线
账号封禁 —— 指定天数封禁、永久封禁、设定解封时间
持久层扩展 —— 可集成Redis、Memcached等专业缓存中间件,重启数据不丢失
分布式会话 —— 提供jwt集成、共享数据中心两种分布式会话方案
微服务网关鉴权 —— 适配Gateway、ShenYu、Zuul等常见网关的路由拦截认证
单点登录 —— 内置三种单点登录模式:无论是否跨域、是否共享Redis,都可以搞定
OAuth2.0认证 —— 基于RFC-6749标准编写,OAuth2.0标准流程的授权认证,支持openid模式
二级认证 —— 在已登录的基础上再次认证,保证安全性
Basic认证 —— 一行代码接入 Http Basic 认证
独立Redis —— 将权限缓存与业务缓存分离
临时Token验证 —— 解决短时间的Token授权问题
模拟他人账号 —— 实时操作任意用户状态数据
临时身份切换 —— 将会话身份临时切换为其它账号
前后台分离 —— APP、小程序等不支持Cookie的终端
同端互斥登录 —— 像QQ一样手机电脑同时在线,但是两个手机上互斥登录
多账号认证体系 —— 比如一个商城项目的user表和admin表分开鉴权
花式token生成 —— 内置六种Token风格,还可:自定义Token生成策略、自定义Token前缀
注解式鉴权 —— 优雅的将鉴权与业务代码分离
路由拦截式鉴权 —— 根据路由拦截鉴权,可适配restful模式
自动续签 —— 提供两种Token过期策略,灵活搭配使用,还可自动续签
会话治理 —— 提供方便灵活的会话查询接口
记住我模式 —— 适配[记住我]模式,重启浏览器免验证
密码加密 —— 提供密码加密模块,可快速MD5、SHA1、SHA256、AES、RSA加密
全局侦听器 —— 在用户登陆、注销、被踢下线等关键性操作时进行一些AOP操作
开箱即用 —— 提供SpringMVC、WebFlux等常见web框架starter集成包,真正的开箱即用
更多功能正在集成中… —— 如有您有好想法或者建议,欢迎加群交流
————————————————
版权声明:本文为CSDN博主「xiaocstudy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43967582/article/details/122075950

你可能感兴趣的:(java,redis,数据库)