Satoken原理详解

一、Satoken原理

Satoken是基于Cookie与Session的一种轻量级权限认证框架,它通过将登录成功后的用户信息存储在session中,并基于此生成一个token,再将token存储在cookie中返回给客户端,从而实现身份认证和权限校验的功能。

Satoken的核心代码如下:

public class SaTokenManager {

    /**
     * 创建指定user_id的token 
     * @param loginId 账号id 
     * @return token 
     */
    public String createToken(Object loginId) {
        // 生成 sessionId
        String sessionId = SessionIdGenerator.generateId();
        // 创建 session 
        SaSession session = SaManager.getSaSession(sessionId, true);
        // 标记用户已登录 
        session.setAttribute("loginId", loginId);
        // 创建 Session-Token 
        String tokenValue = TokenValueGenerator.generateValue();
        SaToken token = SaManager.createToken(tokenValue);
        // 关联 session 
        SaManager.bindToken(token, session);
        // 将 session id 写到 cookie 
        SaManager.getResponse().addCookie(SaConstant.TOKEN_NAME, tokenValue);
        return tokenValue;
    }

    /**
     * 删除指定tokenId对应的session
     * @param tokenValue tokenId 
     */
    public void removeToken(String tokenValue) {
        SaManager.logoutByTokenValue(tokenValue);
    }

    /**
     * 根据Token-Value 获取对应userid 
     * @param tokenValue Token值 
     * @return userid,如果未登录则返回null 
     */
    public Object getUserIdByToken(String tokenValue) {
        return SaManager.getObjectValue(tokenValue, "loginId");
    }

    /**
     * 根据Token-Value 获取对应session 
     * @param tokenValue Token值 
     * @return session,如果未登录则返回null 
     */
    public SaSession getSessionByToken(String tokenValue) {
        return SaManager.getSessionByToken(tokenValue);
    }
}

二、Satoken跨域

Satoken可以支持跨域访问,只需要在服务器端配置一下即可。例如,我们可以使用SpringBoot来进行配置:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

三、Goldengate原理

Satoken集成了类似于Goldengate的功能,可以在登陆成功后将用户信息同步到其他应用的session中。具体实现可以继承SaTokenListener,实现onLogout、onLoginSuccess等方法即可。

以下是一个典型的Goldengate应用的代码示例:

public class GoldenGateSaTokenListener implements SaTokenListener {

    /**
     * 登录成功后同步用户信息到其他应用 
     */
    @Override
    public void onLoginSuccess(String loginId, ServletRequest request, SaToken token) {
        // 获取当前应用的所有Url 
        List<String> urlList = getApplicationUrls();
        // 将用户信息同步到其他应用 
        for (String url : urlList) {
            HttpUtil.post(url + "/goldengate/syncUser", loginId);
        }
    }

    /**
     * 用户退出时通知其他应用删除该用户的session   
     */
    @Override
    public void onLogout(String loginId, ServletRequest request, SaToken token) {
        // 获取当前应用的所有Url 
        List<String> urlList = getApplicationUrls();
        // 将退出消息通知其他应用 
        for (String url : urlList) {
            HttpUtil.post(url + "/goldengate/removeUser", loginId);
        }
    }

    /**
     * 获取当前应用所有Url 
     */
    private List<String> getApplicationUrls() {
        // 省略获取Url列表的代码 
    }
}

四、Satoken真的好用吗

Satoken具有轻量、易用、高性能、安全等优势,其使用非常简单,十分适合做权限认证。此外,Satoken还具备 Goldengate等高级功能,可轻松支持微服务、分布式等场景。因此,Satoken值得我们去尝试使用。

五、Satoken权限认证

Satoken具有基于角色、权限、URL等粒度的权限认证功能,使用示例如下:

public class MyController {

    /**
     * 需要admin权限 
     * @return 
     */
    @SaCheckRole("admin")
    @GetMapping("/manager")
    public String manager() {
        return "manager";
    }

    /**
     * 需要user或admin权限 
     * @return 
     */
    @SaCheckPermission("user:read")
    @PostMapping("/user/list")
    public String userList() {
        return "userList";
    }
}

六、Satoken官网

Satoken的官网为:https://sa-token.dev33.cn/

七、Satoken怎么样

Satoken在功能上与传统的Shiro、Spring Security等认证框架相比并没有多大的优势,但它的性能要更加高效,并且使用起来非常方便,适合小型项目的开发。

八、Satoken微服务

Satoken完全支持微服务的使用,例如在Spring Cloud微服务架构中,可以通过配置SaTokenServerConfigurer来实现跨微服务的数据同步。代码示例如下:

@Configuration
public class SaTokenServerConfig implements SaTokenServerConfigurer {

    @Autowired
    private DiscoveryClient discoveryClient;

    @Override
    public boolean refreshTokenById(String tokenValue, String tokenKey, String tokenId) {
        // 根据tokenId在所有微服务中查找该token对应的session,然后重新生成token
        List<ServiceInstance> instances = discoveryClient.getInstances(SERVER_APP_NAME);
        for (ServiceInstance instance : instances) {
            String url = instance.getUri() + "/api/token/refresh?id=" + tokenId;
            try {
                restTemplate.put(url, null);
                return true;
            } catch (RestClientException e) {
                e.printStackTrace();
            }
        }
        return false;
    }
}

九、Satoken Gateway

Satoken也支持在Spring Cloud Gateway中使用,只需要在gateway中添加一个TokenFilter即可,该filter可以实现用户身份认证、权限校验等功能。具体实现可以参考以下代码:

public class TokenFilter implements GatewayFilter, Ordered {

    @Autowired
    private UserService userService;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 认证用户身份 
        String tokenValue = getAuthorizationToken(exchange.getRequest());
        SaToken token = SaManager.checkToken(tokenValue);
        if (!token.isLogin()) {
            return ResponseUtil.unauthorized(exchange, "未登录或已过期");
        }
        // 校验用户权限 
        String uri = exchange.getRequest().getURI().getPath();
        boolean hasPermission = userService.checkPermission(token.getObjectId(), uri);
        if (!hasPermission) {
            return ResponseUtil.forbidden(exchange);
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -200;
    }
}

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/201160.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-06 11:30
下一篇 2024-12-06 11:30

相关推荐

  • Harris角点检测算法原理与实现

    本文将从多个方面对Harris角点检测算法进行详细的阐述,包括算法原理、实现步骤、代码实现等。 一、Harris角点检测算法原理 Harris角点检测算法是一种经典的计算机视觉算法…

    编程 2025-04-29
  • 瘦脸算法 Python 原理与实现

    本文将从多个方面详细阐述瘦脸算法 Python 实现的原理和方法,包括该算法的意义、流程、代码实现、优化等内容。 一、算法意义 随着科技的发展,瘦脸算法已经成为了人们修图中不可缺少…

    编程 2025-04-29
  • 神经网络BP算法原理

    本文将从多个方面对神经网络BP算法原理进行详细阐述,并给出完整的代码示例。 一、BP算法简介 BP算法是一种常用的神经网络训练算法,其全称为反向传播算法。BP算法的基本思想是通过正…

    编程 2025-04-29
  • GloVe词向量:从原理到应用

    本文将从多个方面对GloVe词向量进行详细的阐述,包括其原理、优缺点、应用以及代码实现。如果你对词向量感兴趣,那么这篇文章将会是一次很好的学习体验。 一、原理 GloVe(Glob…

    编程 2025-04-27
  • 编译原理语法分析思维导图

    本文将从以下几个方面详细阐述编译原理语法分析思维导图: 一、语法分析介绍 1.1 语法分析的定义 语法分析是编译器中将输入的字符流转换成抽象语法树的一个过程。该过程的目的是确保输入…

    编程 2025-04-27
  • 神经网络代码详解

    神经网络作为一种人工智能技术,被广泛应用于语音识别、图像识别、自然语言处理等领域。而神经网络的模型编写,离不开代码。本文将从多个方面详细阐述神经网络模型编写的代码技术。 一、神经网…

    编程 2025-04-25
  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25
  • MPU6050工作原理详解

    一、什么是MPU6050 MPU6050是一种六轴惯性传感器,能够同时测量加速度和角速度。它由三个传感器组成:一个三轴加速度计和一个三轴陀螺仪。这个组合提供了非常精细的姿态解算,其…

    编程 2025-04-25
  • Linux修改文件名命令详解

    在Linux系统中,修改文件名是一个很常见的操作。Linux提供了多种方式来修改文件名,这篇文章将介绍Linux修改文件名的详细操作。 一、mv命令 mv命令是Linux下的常用命…

    编程 2025-04-25
  • git config user.name的详解

    一、为什么要使用git config user.name? git是一个非常流行的分布式版本控制系统,很多程序员都会用到它。在使用git commit提交代码时,需要记录commi…

    编程 2025-04-25

发表回复

登录后才能评论