为了账号安全,请及时绑定邮箱和手机立即绑定

Sa-Token学习:新手入门指南

概述

本文提供了Sa-Token学习的全面指南,涵盖Sa-Token的基本概念、主要功能和适用场景。文章详细介绍了如何在项目中搭建和配置Sa-Token,并通过示例代码展示了Token生成、校验、权限控制等基础操作。Sa-Token学习包括环境搭建、基础使用教程和实战演练,帮助开发者快速掌握Sa-Token的使用方法。

Sa-Token学习:新手入门指南
Sa-Token简介

Sa-Token是什么

Sa-Token 是一款基于 Java 语言,专注于 Web 应用的权限框架。它主要提供了一套完整的权限控制和服务端公共逻辑处理机制,可以帮助开发者快速搭建安全、稳定的 Web 应用。Sa-Token 主要用于会话管理、权限控制、Token 生成和校验、分布式缓存等场景。

Sa-Token的主要功能

  • Token 生成与校验:生成唯一标识符,用于用户身份验证。
  • 权限控制:支持细粒度的权限控制,包括基于角色、基于方法等。
  • 分布式缓存:支持 Redis 等分布式缓存,提高系统性能。
  • 会话管理:提供会话的创建、删除、更新等操作。
  • Token 自动刷新:支持 Token 的自动刷新,避免手动刷新 Token 的麻烦。
  • 高并发处理:具有高性能和高并发处理能力。

Sa-Token的适用场景

  • Web 应用权限控制:适用于 Web 应用中的用户登录、权限校验等场景。
  • API 接口保护:可以为 Web 服务中的 API 接口提供安全保护。
  • 分布式系统:适用于分布式环境中的会话管理和缓存处理。
  • 单点登录:支持单点登录功能,使用户在多个应用之间无缝切换。
  • 高并发场景:适用于高并发的 Web 应用,保证系统的稳定性和性能。
环境搭建

下载并引入Sa-Token

要使用 Sa-Token,首先需要下载并引入 Sa-Token 的依赖。通常,我们会选择使用 Maven 或 Gradle 等构建工具来管理依赖。

使用 Maven 时,在 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>com.github.sakebook</groupId>
    <artifactId>sa-token</artifactId>
    <version>1.39</version>
</dependency>

使用 Gradle 时,在 build.gradle 文件中添加以下依赖:

implementation 'com.github.sakebook:sa-token:1.39'

配置Sa-Token的初始化设置

安装依赖后,需要进行 Sa-Token 的初始化设置。在 Spring Boot 应用中,可以在 application.ymlapplication.properties 文件中进行配置。

例如,在 application.yml 文件中配置:

sa-token:
  enabled: true
token-name: stoken
token-ttl: 3600 # Token 有效时间(秒)

application.properties 文件中配置:

sa-token.enabled=true
sa-token.token-name=stoken
sa-token.token-ttl=3600 # Token 有效时间(秒)

然后,创建一个配置类 SaTokenConfig 来初始化 Sa-Token:

import cn.dev33.satoken.stp.StpUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SaTokenConfig {

    @Bean
    public void initSaToken() {
        StpUtil.config();
    }
}

常见问题解决

在配置和使用 Sa-Token 过程中,可能会遇到一些常见问题。以下是一些常见问题及其解决方法:

  1. 依赖冲突:确保项目中没有其他依赖与 Sa-Token 产生冲突。
  2. 配置不生效:检查配置文件中的配置项是否正确,是否被正确加载。
  3. 权限控制失效:确保在访问接口时正确生成和传递 Token,并且在控制器方法中调用权限校验方法。

如果遇到具体问题,可以参考 Sa-Token 的官方文档和社区支持。

基础使用教程

生成和校验Token

生成 Token 的过程通常在用户登录时完成。首先,用户提交用户名和密码,服务端验证成功后,生成一个唯一的 Token,并返回给客户端。

用户登录生成Token

生成 Token 的示例代码如下:

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.StpLogic;

public class SaTokenDemo {

    public static void main(String[] args) {
        // 创建 StpLogic 对象
        StpLogic stpLogic = new StpLogic();

        // 生成一个 Token
        String token = stpLogic.getTokenValue();

        // 输出生成的 Token
        System.out.println("生成的 Token: " + token);
    }
}

校验 Token 的过程通常在每次请求前完成。服务端需要验证客户端发送的 Token 是否有效。

校验Token

校验 Token 的示例代码如下:

public class SaTokenDemo {

    public static void main(String[] args) {
        // 创建 StpLogic 对象
        StpLogic stpLogic = new StpLogic();

        // 验证 Token 是否有效
        boolean isValid = stpLogic.isLogin("your-token");

        // 输出验证结果
        System.out.println("Token 是否有效: " + isValid);
    }
}

Token的过期时间和刷新

Token 的过期时间可以通过配置文件进行设置,例如在 application.yml 中设置 token-ttl

sa-token:
  token-ttl: 3600 # Token 有效时间(秒)

过期时间到达后,Token 将无法通过验证。为了保持用户的登录状态,可以实现 Token 的自动刷新。Sa-Token 支持在用户登录后自动刷新 Token,以延长 Token 的有效期。

自动刷新Token

自动刷新 Token 的示例代码如下:

import cn.dev33.satoken.stp.StpUtil;

public class SaTokenDemo {

    public static void main(String[] args) {
        // 用户登录并生成 Token
        StpUtil.login("user1");

        // 设置 Token 刷新策略
        StpUtil.setRefreshStrategy(StpUtil.REFRESH_STRATEGY.REPEAT_REFRESH);

        // 输出当前 Token
        System.out.println("当前 Token: " + StpUtil.getTokenValue());

        // 模拟过期时间到达
        Thread.sleep(3500); // 模拟等待时间

        // 刷新 Token
        StpUtil.refreshToken();

        // 输出刷新后的 Token
        System.out.println("刷新后的 Token: " + StpUtil.getTokenValue());
    }
}

基于Token的权限控制

通过 Token 进行权限控制,可以在每次请求前验证用户是否有执行该操作的权限。

定义权限和角色

权限控制的示例代码如下:

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;

public class SaTokenDemo {

    public static void main(String[] args) {
        // 用户登录并生成 Token
        StpUtil.login("user1");

        // 设置权限
        StpUtil.setPermission("user1", "read");

        try {
            // 检查是否有权限执行操作
            boolean hasPermission = StpUtil.checkPermission("read");

            // 输出权限检查结果
            System.out.println("用户是否具有读取权限: " + hasPermission);

            // 检查是否有权限执行另一个操作
            boolean hasPermission2 = StpUtil.checkPermission("write");

            // 输出权限检查结果
            System.out.println("用户是否具有写入权限: " + hasPermission2);

        } catch (NotLoginException e) {
            e.printStackTrace();
        } catch (NotPermissionException e) {
            e.printStackTrace();
        }
    }
}
实战演练

创建一个简单的登录界面

首先,创建一个简单的登录界面,用于收集用户名和密码,并将这些信息传递给后端服务。

HTML示例代码

<!DOCTYPE html>
<html>
<head>
    <title>Login Page</title>
</head>
<body>
    <form action="/login" method="post">
        <label for="username">用户名:</label>
        <input type="text" id="username" name="username">
        <br>
        <label for="password">密码:</label>
        <input type="password" id="password" name="password">
        <br>
        <input type="submit" value="登录">
    </form>
</body>
</html>

后端处理登录逻辑

后端示例代码(Spring Boot 控制器):

import cn.dev33.satoken.stp.StpUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {

    @PostMapping("/login")
    public String login(@RequestParam String username, @RequestParam String password) {
        // 验证用户名和密码
        if (username.equals("user1") && password.equals("password123")) {
            // 用户登录并生成 Token
            StpUtil.login(username);
            return "登录成功,Token: " + StpUtil.getTokenValue();
        } else {
            return "用户名或密码错误";
        }
    }
}

使用Sa-Token实现用户登录和验证

登录后,用户需要使用 Token 来访问受保护的资源。在每次请求时,需要校验证 Token 是否有效。

后端验证Token

后端示例代码(Spring Boot 控制器):

import cn.dev33.satoken.stp.StpUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ResourceController {

    @GetMapping("/protected")
    public String protectedResource(@RequestParam String token) {
        // 验证 Token 是否有效
        if (StpUtil.isLogin(token)) {
            return "访问成功";
        } else {
            return "Token 无效";
        }
    }
}

客户端请求示例代码

import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class SaTokenDemo {

    public static void main(String[] args) throws Exception {
        // 创建 HttpClient 实例
        HttpClient client = HttpClient.newHttpClient();

        // 创建 HttpRequest 对象
        HttpRequest request = HttpRequest.newBuilder()
                .uri(new java.net.URI("http://localhost:8080/protected?token=your-token"))
                .build();

        // 发送请求
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // 输出响应结果
        System.out.println("响应结果: " + response.body());
    }
}

实现基于角色的权限管理

在实际应用中,用户可能属于不同的角色,并且每个角色有不同的权限。可以通过角色进行权限控制。

后端实现角色权限控制

后端示例代码(Spring Boot 控制器):

import cn.dev33.satoken.stp.StpUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RoleController {

    @GetMapping("/admin-only")
    public String adminOnly(@RequestParam String token) {
        // 设置权限
        StpUtil.setPermission(token, "admin");

        // 检查是否有权限执行操作
        if (StpUtil.checkPermission("admin", token)) {
            return "访问成功";
        } else {
            return "您没有权限访问此资源";
        }
    }
}

客户端请求示例代码

import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class SaTokenDemo {

    public static void main(String[] args) throws Exception {
        // 创建 HttpClient 实例
        HttpClient client = HttpClient.newHttpClient();

        // 创建 HttpRequest 对象
        HttpRequest request = HttpRequest.newBuilder()
                .uri(new java.net.URI("http://localhost:8080/admin-only?token=your-token"))
                .build();

        // 发送请求
        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // 输出响应结果
        System.out.println("响应结果: " + response.body());
    }
}
常见问题解答

Token被篡改怎么办

当检测到 Token 被篡改时,可以采取以下措施:

  1. 重新生成 Token:在检测到 Token 被篡改后,重新生成一个新的 Token 发送给客户端。
  2. 禁用 Token:在检测到 Token 被篡改后,立即禁用当前 Token,防止进一步的非法访问。
  3. 记录日志:记录 Token 被篡改的详细信息,以便后续审计和分析。

示例代码:

import cn.dev33.satoken.stp.StpUtil;

public class SaTokenDemo {

    public static void main(String[] args) {
        // 检测 Token 是否被篡改
        if (StpUtil.checkTokenTamper("your-token")) {
            // 重新生成 Token
            StpUtil.logout("your-token");
            StpUtil.login("user1");
            System.out.println("Token 已被重新生成");
        } else {
            System.out.println("Token 未被篡改");
        }
    }
}

如何处理Token过期

当 Token 过期时,可以采取以下措施:

  1. 自动刷新 Token:在用户登录后自动刷新 Token,以延长 Token 的有效期。
  2. 提示用户重新登录:当 Token 过期时,提示用户重新登录。
  3. 使用长寿命 Token:为某些重要的操作使用长寿命 Token,减少刷新的频率。

示例代码:

import cn.dev33.satoken.stp.StpUtil;

public class SaTokenDemo {

    public static void main(String[] args) {
        // 用户登录并生成 Token
        StpUtil.login("user1");

        // 设置 Token 刷新策略
        StpUtil.setRefreshStrategy(StpUtil.REFRESH_STRATEGY.REPEAT_REFRESH);

        // 模拟过期时间到达
        Thread.sleep(3500); // 模拟等待时间

        // 刷新 Token
        StpUtil.refreshToken();

        // 输出刷新后的 Token
        System.out.println("刷新后的 Token: " + StpUtil.getTokenValue());
    }
}

如何提高安全性

为了提高安全性,可以采取以下措施:

  1. 使用长寿命 Token:为某些重要的操作使用长寿命 Token,减少刷新的频率。
  2. 启用 SSL:使用 SSL 加密通信过程,保护数据传输的安全性。
  3. 避免直接在前端存储 Token:将 Token 存储在 HttpOnly Cookie 中,避免前端 JavaScript 代码直接访问 Token。
  4. 使用 Salt 值:在生成 Token 时,添加 Salt 值以增加 Token 的复杂度,提高安全性。

示例代码:


import cn.dev33.satoken.stp.StpUtil;

public class SaTokenDemo {

    public static void main(String[] args) {
        // 用户登录并生成 Token
        String token = StpUtil.login("user1", "salt-value");

        // 输出生成的 Token
        System.out.println("生成的 Token: " + token);
    }
}
``

通过以上步骤,可以有效地提高系统的安全性和稳定性。希望这些示例代码和指南对您有所帮助。
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消