Sa-Token Thymeleaf 标签方言:在页面中优雅实现登录、角色与权限控制
2026/9/14 19:42:57 网站建设 项目流程

Sa-Token Thymeleaf 标签方言:在页面中优雅实现登录、角色与权限控制

【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架,让鉴权变得简单、优雅!—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token

本篇文章讲解 Sa-Token 官方插件sa-token-thymeleaf的完整用法:如何把它引入 Thymeleaf 模板引擎、如何注册标签方言 Bean、如何使用sa:前缀下的登录判断 / 角色判断 / 权限判断标签,以及如何通过注入全局变量stp在页面中直接调用 Sa-Token 的底层 API。读完本文,你将能够在 Thymeleaf 页面中零 Java 代码地完成大部分鉴权显隐控制,并理解每个标签背后的实现原理。


1、标签方言是什么

Sa-Token 的核心能力(登录认证、角色认证、权限认证)默认是在 Java 层通过StpUtil调用的。但在 Web 开发中,很多鉴权需求发生在视图层:例如"登录用户才能看到这段内容""只有 admin 角色才能看到管理按钮""没有 user-add 权限就不渲染新增按钮"。

sa-token-thymeleaf插件为 Thymeleaf 提供了一套自定义标签方言(Dialect),让你可以直接在 HTML 标签属性上写sa:loginsa:hasRole="admin"这类指令。模板渲染时,Thymeleaf 引擎会根据当前登录状态动态决定保留或移除对应元素,从而实现页面级的权限控制,无需编写任何 Java 判断逻辑。

从源码看,该方言由三个文件构成:

  • SaTokenDialect.java:方言主体,继承 Thymeleaf 的AbstractProcessorDialect,注册全部标签处理器;
  • SaTokenTagProcessor.java:属性标签处理器,负责执行判断表达式并按结果保留/移除元素;
  • Sa-Token-Dialect.xml:方言描述文件,声明命名空间与各属性的说明文档。

2、引入依赖

首先确保项目已经引入 Thymeleaf 依赖(Spring Boot 项目通常使用spring-boot-starter-thymeleaf),然后在此基础上继续添加sa-token-thymeleaf插件。

Maven 方式:

<!-- 在 thymeleaf 标签中使用 Sa-Token --> <dependency> <groupId>cn.dev33</groupId> <artifactId>sa-token-thymeleaf</artifactId> <version>${sa.top.version}</version> </dependency>

Gradle 方式:

// 在 thymeleaf 标签中使用 Sa-Token implementation 'cn.dev33:sa-token-thymeleaf:${sa.top.version}'

说明:${sa.top.version}是 Sa-Token 版本号占位符,请替换为你实际使用的版本。仓库中的演示工程 sa-token-demo-thymeleaf/pom.xml 使用的是1.46.0,可作参考。

从插件自身的 pom.xml 可以看到,它仅依赖sa-token-core(Sa-Token 核心)与thymeleaf(且标记为optional),不会引入多余的传递依赖,非常轻量。

3、注册标签方言对象

依赖引入后,需要在 Spring 配置类中把SaTokenDialect注册为 Bean,Thymeleaf 才能识别并启用这套方言。

SaTokenConfigure配置类中注册 Bean:

@Configuration public class SaTokenConfigure { // Sa-Token 标签方言 (Thymeleaf版) @Bean public SaTokenDialect getSaTokenDialect() { return new SaTokenDialect(); } }

仓库演示工程中的 SaTokenConfigure.java 就是完全一致的写法。

关于底层 StpLogic(源码细节)SaTokenDialect有两个构造方法。无参构造内部实际调用的是this("sa", 1000, StpUtil.stpLogic),即默认方言名称为sa、处理器优先级为1000、底层复用StpUtil的全局StpLogic;你也可以通过new SaTokenDialect(name, precedence, stpLogic)自定义方言名称、优先级和所绑定的StpLogic(适用于多账号体系,让不同页面绑定不同登录体系)。这一点在 SaTokenDialectTest.java 的defaultConstructor_usesSaPrefixAndGlobalStpLogiccustomConstructor_keepsNameAndPrecedence两个测试用例中得到了直接验证。

4、使用标签方言

注册完成后,就可以在 Thymeleaf 页面中直接使用sa:前缀的标签了。所有标签都会在渲染时执行一次判断:条件满足则保留元素(并把sa:属性从标签上移除),条件不满足则整个元素(连同其子内容)被删除,这是 Thymeleaf 自定义属性处理器SaTokenTagProcessor.doProcessstructureHandler.removeElement()的行为,详见 SaTokenTagProcessor.java。

4.1、登录判断

<h2>标签方言测试页面</h2> <p> 登录之后才能显示: <span sa:login>value</span> </p> <p> 不登录才能显示: <span sa:notLogin>value</span> </p>
  • sa:login:当前账号已登录时显示该元素;
  • sa:notLogin:当前账号未登录时显示该元素。

这两个标签底层调用的是stpLogic.isLogin()(见 SaTokenDialect.java),login取真值显示、notLogin取反后显示。

4.2、角色判断

<p> 具有角色 admin 才能显示: <span sa:hasRole="admin">value</span> </p> <p> 同时具备多个角色才能显示: <span sa:hasRoleAnd="admin, ceo, cto">value</span> </p> <p> 只要具有其中一个角色就能显示: <span sa:hasRoleOr="admin, ceo, cto">value</span> </p> <p> 不具有角色 admin 才能显示: <span sa:notRole="admin">value</span> </p>
  • sa:hasRole="admin":具有指定角色才显示;
  • sa:hasRoleAnd="admin, ceo, cto"同时具备多个角色才显示(多个值用逗号分隔);
  • sa:hasRoleOr="admin, ceo, cto"只要具备其中任一角色就显示;
  • sa:notRole="admin"不具有指定角色才显示。

从源码看,多角色/多权限值会先经过SaTokenDialect.toArray(value)转换成字符串数组,内部使用SaFoxUtil.convertStringToList按逗号切分并自动去除空格,因此"admin, ceo, cto""admin,ceo,cto"等价;对应测试toArray_splitsAndTrims也验证了" admin , user "会被正确解析为["admin", "user"]

另外,方言 XML 描述文件 Sa-Token-Dialect.xml 中还声明了一个sa:lackRole属性,语义与notRole相同("不具有指定角色才能显示元素"),但文档标注为"未来版本可能废弃,建议更换为 notRole"。同理还有sa:lackPermission对应notPermission新项目建议直接使用notRole/notPermission

4.3、权限判断

<p> 具有权限 user-add 才能显示: <span sa:hasPermission="user-add">value</span> </p> <p> 同时具备多个权限才能显示: <span sa:hasPermissionAnd="user-add, user-delete, user-get">value</span> </p> <p> 只要具有其中一个权限就能显示: <span sa:hasPermissionOr="user-add, user-delete, user-get">value</span> </p> <p> 不具有权限 user-add 才能显示: <span sa:notPermission="user-add">value</span> </p>
  • sa:hasPermission="user-add":具有指定权限才显示;
  • sa:hasPermissionAnd="user-add, user-delete, user-get":同时具备全部权限才显示;
  • sa:hasPermissionOr="user-add, user-delete, user-get":具备其中任一权限就显示;
  • sa:notPermission="user-add":不具有指定权限才显示。

权限数据的来源由项目中的StpInterface实现类提供。仓库演示工程 StpInterfaceImpl.java 模拟返回了user-adduser-delete等权限码集合以及adminsuper-admin角色集合,可对照理解标签判断的数据从何而来。

4.4、渲染行为验证(测试用例)

仓库在 SaTokenDialectTest.java 中对全部标签的显隐行为做了完整测试,例如:

  • hasRoleTag_rendersOrRemoves:拥有admin角色时<div>保留,只有user角色时整个元素被移除;
  • hasRoleAndTag_requiresAllRolessa:hasRoleAnd="admin,ops"要求两个角色齐全才显示;
  • hasRoleOrTag_requiresAnyRolesa:hasRoleOr="admin,ops"只要具备其一即可;
  • hasRoleTag_hiddenWhenNotLogin未登录时hasRole等标签一律隐藏(内部通过捕获NotLoginException返回 false),这个行为非常实用,避免未登录页面暴露敏感区域;
  • getProcessors_registers13Processors:方言共注册 13 个处理器(12 个鉴权标签 + 1 个用于移除<html>命名空间声明的处理器)。

5、在页面中调用 Sa-Token 相关 API

标签方言可以满足大多数场景下的权限判断。但有时候我们依然需要更加灵活地在页面中调用 Sa-Token 框架 API,例如读取SaSession中存放的业务数据、获取当前登录账号 ID 等。此时可以借助 Thymeleaf 的全局静态变量机制,把StpLogic暴露给页面。

首先在SaTokenConfigure配置类中为 Thymeleaf 配置全局对象:

@Configuration public class SaTokenConfigure{ // ... 其它代码 // 为 Thymeleaf 注入全局变量,以便在页面中调用 Sa-Token 的方法 @Autowired private void configureThymeleafStaticVars(ThymeleafViewResolver viewResolver) { viewResolver.addStaticVariable("stp", StpUtil.stpLogic); } }

[!WARNING| label:注意] 如果SaTokenConfigure继承了WebMvcConfigurer等类,可能会造成循环依赖,如果遇到,请新建一个其他配置类完成此项配置。

然后就可以在页面上调用StpLogic的 API 了,例如:

<p>调用 StpLogic 方法调用测试</p> <p th:if="${stp.isLogin()}"> 从SaSession中取值: <span th:text="${stp.getSession().get('name')}"></span> </p>

这里stpStpUtil.stpLogic,因此在页面中stp.isLogin()stp.getSession().get('name')stp.getLoginId()StpLogic的公开方法都可以直接调用,与 Java 层的StpUtil完全同源。StpLogic是整个 Sa-Token 登录逻辑门面的实现类,多账号体系下每个 loginType 对应一个独立的StpLogic实例,这也是方言构造方法接受StpLogic参数的意义所在。

6、代码提示

如果想在写标签属性时获得 IDE 的代码提示(补全sa:loginsa:hasRole等属性),只需在 HTML 头部声明增加上对应的命名空间即可:

<!DOCTYPE html> <html lang="zh" xmlns:sa="http://www.thymeleaf.org/extras/sa-token"> <head> <!-- 代码 --> </head> <body> <!-- 代码 --> </body> </html>

命名空间http://www.thymeleaf.org/extras/sa-token与方言描述文件 Sa-Token-Dialect.xml 中声明的namespace-uri保持一致。声明命名空间属于纯提示性质,即使不写,标签在运行时也能正常工作。

7、常用标签速查表

标签属性底层调用(基于StpLogic显示条件
sa:loginisLogin()已登录
sa:notLogin!isLogin()未登录
sa:hasRole="admin"hasRole("admin")具有指定角色
sa:hasRoleAnd="a, b"hasRoleAnd([a, b])同时具备全部角色
sa:hasRoleOr="a, b"hasRoleOr([a, b])具备任一角色
sa:notRole="admin"!hasRole("admin")不具有指定角色
sa:lackRole="admin"!hasRole("admin")notRole(建议使用notRole
sa:hasPermission="user-add"hasPermission("user-add")具有指定权限
sa:hasPermissionAnd="a, b"hasPermissionAnd([a, b])同时具备全部权限
sa:hasPermissionOr="a, b"hasPermissionOr([a, b])具备任一权限
sa:notPermission="user-add"!hasPermission("user-add")不具有指定权限
sa:lackPermission="user-add"!hasPermission("user-add")notPermission(建议使用notPermission

8、小结

sa-token-thymeleaf插件以 Thymeleaf 自定义方言的形式,把 Sa-Token 的登录、角色、权限三大鉴权能力无缝下沉到视图层,让你在 HTML 中即可完成精细的显隐控制,同时通过stp全局变量保留了调用StpLogic全量 API 的灵活性。其实现路径清晰:SaTokenDialect负责注册处理器,SaTokenTagProcessor负责按判断结果渲染或移除元素,方言测试 与 演示工程 提供了可直接运行的参考。如果你是 Spring Boot + Thymeleaf 技术栈,这套标签方言能显著简化页面级权限控制的代码量。

【免费下载链接】Sa-Token✨ 开源、免费、一站式 Java 权限认证框架,让鉴权变得简单、优雅!—— 登录认证、权限认证、分布式 Session 会话、微服务网关鉴权、SSO 单点登录、OAuth2.0 统一认证、jwt 集成、API Key 秘钥授权、API 参数签名项目地址: https://gitcode.com/GitHub_Trending/sa/Sa-Token

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询