SaToken单体基础配置

基础.pom依赖, 注意版本,这里我用的是<sa-token.version>1.38.0</sa-token.version>, 而且这里是单体,不是微服务架构的依赖,微服务依赖看官网,有所不同

  <!-- Sa-Token 权限认证 -->
  <dependency>
      <groupId>cn.dev33</groupId>
      <artifactId>sa-token-spring-boot3-starter</artifactId>
      <version>${sa-token.version}</version>
  </dependency>
  <!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
  <dependency>
      <groupId>cn.dev33</groupId>
      <artifactId>sa-token-redis-jackson</artifactId>
      <version>${sa-token.version}</version>
  </dependency>

接下来配置全局过滤器, 这里自己实现异常枚举类ResponseCodeEnum

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import com.quanxiaoha.weblog.common.enums.ResponseCodeEnum;
import com.quanxiaoha.weblog.common.exception.BizException;
import com.quanxiaoha.weblog.common.utils.Response;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;

@Slf4j
/**
 * [Sa-Token 权限认证] 配置类
 */
@Configuration
public class SaTokenConfigure {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 注册 [Sa-Token全局过滤器]
     */
    @Bean
    public SaServletFilter getSaServletFilter() {
        return new SaServletFilter()
                // 拦截地址
                .addInclude("/admin/**")    /* 拦截全部path */
                // 鉴权方法:每次访问进入
                .setAuth(obj -> {
                    // 登录校验
                    SaRouter.match("/admin/**") // 拦截所有路由
                            .check(r -> StpUtil.checkLogin()); // 校验是否登录

                    // 文章模块
                    SaRouter.match("/admin/article/**")
                            .notMatch("/admin/article/list")
                            .notMatch("/admin/article/detail")
                            .check(r -> StpUtil.checkRole("ROLE_ADMIN"));
                })  
                // 异常处理方法
                .setError(e -> {
                    log.error("Sa-Token auth error: {}", e.getMessage());

                    // 根据异常类型,构造统一的 Response 响应体
                    Response<?> body;
                    if (e instanceof NotLoginException) {
                        body = Response.fail(ResponseCodeEnum.UNAUTHORIZED);
                    } else if (e instanceof NotRoleException || e instanceof NotPermissionException) {
                        body = Response.fail(ResponseCodeEnum.FORBIDDEN);
                    } else if (e instanceof BizException biz) {
                        body = Response.fail(biz);
                    } else {
                        body = Response.fail(ResponseCodeEnum.SYSTEM_ERROR);
                    }
                    // 设置返回头为 JSON,返回 JSON 字符串,避免被当作普通字符串输出
                    try {
                        SaHolder.getResponse().setHeader("Content-Type", "application/json;charset=UTF-8");
                        return new ObjectMapper().writeValueAsString(body);
                    } catch (Exception ex) {
                        // 兜底:序列化异常时,返回一个固定 JSON 字符串
                        return "{\"success\":false,\"message\":\"出错啦,后台正在努力修复中...\",\"errorCode\":\"10000\",\"data\":null}";
                    }
                });
    }

}

接下来就是权限设置, 这里自己从mapper接口注入拿权限,自己实现对应权限

import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.stp.StpUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Component
@Slf4j
public class StpInterfaceImpl implements StpInterface {


    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Override
    public List<String> getPermissionList(Object o, String s) {
        return List.of();
    }

    @SneakyThrows
    @Override
    public List<String> getRoleList(Object o, String s) {
        String roleName = StpUtil.getLoginIdAsString();

        List roles = new ArrayList<>();
        if(StringUtils.isNoneBlank(roleName)) {
            if(Objects.equals(roleName, "admin")) {
                roles.add("ROLE_ADMIN");
            } else if(Objects.equals(roleName, "test")) {
                roles.add("ROLE_VISITOR");
            }
        }
        return roles;
    }
}

posted @ 2025-12-30 11:51  zouyua  阅读(16)  评论(0)    收藏  举报