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/zh-hk/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

發表回復

登錄後才能評論