本文转载自微信公众号「Java大厂面试官」,作者laker。转载本文请联系Java大厂面试官公众号。
目前我仅以学习和尝鲜为目的来集成,不建议用于公司等正式环境,公司还是建议Shiro和Spring Security那一套。(等我实战一波看看效果再说)
之前我还是挺排斥国产小作坊的开源作品,毕竟不是根红苗正,但是随着近几年国内开源社区的大力发展,以及在平时工作中又接触了解很多,慢慢改变了我的看法,其实国人开源作品还是很香的,其Api简单易用,源码和官方文档都是中文的,功能丰富且能满足很多中国式需求,各种QQ、微信交流群活跃度非常高,总之就是极大程度满足中国式需求。
在权限认证框架领域,使用最多的莫过于Shiro和Spring Security,但是一天在逛同性交友网站(github)的时候,赫然发现了Sa-Token其竟然有2K的star数量,看其中文介绍竟然是轻量级Java权限认证框架,看了下其特性和功能点,就唤起了我强烈的好奇心,于是乎就有了今天的尝鲜。
sa-token是一个轻量级Java权限认证框架,主要解决:登录认证、权限认证、Session会话、单点登录、OAuth2.0 等一系列权限相关问题
框架针对踢人下线、自动续签、前后台分离、分布式会话……等常见业务进行N多适配,通过sa-token,你可以以一种极简的方式实现系统的权限认证部分
与其它权限认证框架相比,sa-token 具有以下优势:
依赖导入
cn.dev33 sa-token-spring-boot-starter 1.15.2
“最新版本去maven中央库自己查询下,当前是1.15.2。
配置文件
你可以零配置启动项目但同时你也可以在application.yml中增加如下配置,定制性使用框架:
- spring:
- # sa-token配置
- sa-token:
- # token名称 (同时也是cookie名称)
- token-name: satoken
- # token有效期,单位s 默认30天, -1代表永不过期
- timeout: 2592000
- # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
- activity-timeout: -1
- # 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
- allow-concurrent-login: true
- # 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
- is-share: false
- # token风格
- token-style: uuid
登录
- @PostMapping("/api/v1/login")
- @ApiOperationSupport(order = 1)
- @ApiOperation(value = "登录")
- public Response login(String userName, String pwd) {
- log.info("login,username:{},pwd:{}", userName, pwd);
- // 模拟 校验用户名密码
- Long userId = check(userName,pwd);
- StpUtil.setLoginId(userId);
- return Response.ok(StpUtil.getTokenInfo());
- }
核心就一行StpUtil.setLoginId(userId),来看看它帮我们做了什么?
源码及其简单,还有很多中文注释,跟着读就行了,直接贴结论。
底层会话等存储使用的是Map
源码如下:
- /**
- * 数据集合
- */
- public Map
dataMap = new ConcurrentHashMap (); - /**
- * 过期时间集合 (单位: 毫秒) , 记录所有key的到期时间 [注意不是剩余存活时间]
- */
- public Map
expireMap = new ConcurrentHashMap ();
调用结果如下:
- Connection: keep-alive
- Content-Type: application/json
- Date: Fri, 09 Apr 2021 07:33:59 GMT
- Keep-Alive: timeout=60
- // 重点
- Set-Cookie: LakerToken=da14afd3f4b648a889a1e51ac3ec53d7; Max-Age=1800; Expires=Fri, 09-Apr-2021 08:03:59 GMT; Path=/
- Transfer-Encoding: chunked
- {
- "code": 200,
- "msg": "",
- "data": {
- "tokenName": "LakerToken",
- "tokenValue": "da14afd3f4b648a889a1e51ac3ec53d7",
- "isLogin": true,
- "loginId": "1",
- "loginKey": "login",
- "tokenTimeout": 1784,
- "sessionTimeout": 1784,
- "tokenSessionTimeout": -2,
- "tokenActivityTimeout": 30,
- "loginDevice": "default-device"
- }
- }
可以看到返回heards中已自动设置:Set-Cookie: LakerToken=da14afd3f4b648a889a1e51ac3ec53d7; Max-Age=1800; Expires=Fri, 09-Apr-2021 08:03:59 GMT; Path=/
登出
- @PostMapping("/api/v1/loginOut")
- @ApiOperationSupport(order = 3)
- @ApiOperation(value = "登出")
- @SaCheckLogin
- public Response loginOut() {
- StpUtil.logout();
- return Response.ok();
- }
核心也是一行StpUtil.logout(),来看看它帮我们做了什么?
请求拦截鉴权
第一步:配置全局拦截器
- @Configuration
- public class MySaTokenConfig implements WebMvcConfigurer {
- /**
- * 注册sa-token的拦截器,打开注解式鉴权功能 (如果您不需要此功能,可以删除此类)
- */
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
- }
- }
第二步:在需要拦截的类或者方法上加注解
例如:
- @GetMapping("/api/v1/tokenInfo")
- @ApiOperationSupport(order = 2)
- @ApiOperation(value = "获取当前会话的token信息")
- @SaCheckLogin
- public Response tokenInfo() {
- return Response.ok(StpUtil.getTokenInfo());
- }
加上@SaCheckLogin则该接口必须处于登录状态才可通过校验。
这里核心拦截校验又是如何工作的呢?可以看下SaAnnotationInterceptor.java源码,基于SpringMvc的拦截器实现的拦截校验。
实现功能如下:
实现流程原理如下:
权限和角色扩展
直接实现StpInterface接口,覆写getPermissionList和getRoleList方法即可。
- @Component
- public class StpInterfaceImpl implements StpInterface {
- /**
- * 返回一个账号所拥有的权限码集合
- */
- @Override
- public List
getPermissionList(Object loginId, String loginKey) { - xxx
- }
- /**
- * 返回一个账号所拥有的角色标识集合
- */
- @Override
- public List
getRoleList(Object loginId, String loginKey) { - xxx
- }
- }
集群环境
Sa-token默认将会话数据保存在内存中,此模式读写速度最快,且避免了序列化与反序列化带来的性能消耗,但是此模式也有一些缺点,比如:重启后数据会丢失,无法在集群模式下共享数据。
为此,sa-token将数据持久操作全部抽象到 SaTokenDao 接口中,此设计可以保证开发者对框架进行灵活扩展,比如我们可以将会话数据存储在 Redis、Memcached等专业的缓存中间件中,做到重启数据不丢失,而且保证分布式环境下多节点的会话一致性。
除了框架内部对SaTokenDao提供的基于内存的默认实现,我们使用官网提供的Redis扩展。
依赖导入
cn.dev33 sa-token-dao-redis-jackson 1.15.2 org.apache.commons commons-pool2
“使用Jackson序列化方式,Session序列化后可读性强,可灵活手动修改
配置文件
- spring:
- # redis配置
- redis:
- # Redis数据库索引(默认为0)
- database: 0
- # Redis服务器地址
- host: 127.0.0.1
- # Redis服务器连接端口
- port: 6379
- # Redis服务器连接密码(默认为空)
- # password:
- # 连接超时时间(毫秒)
- timeout: 1000ms
- lettuce:
- pool:
- # 连接池最大连接数
- max-active: 200
- # 连接池最大阻塞等待时间(使用负值表示没有限制)
- max-wait: -1ms
- # 连接池中的最大空闲连接
- max-idle: 10
- # 连接池中的最小空闲连接
- min-idle: 0
引入依赖和配置后,框架会自动使用Redis存储。
初步尝试还挺不错的,文档和代码示例都很全,基本功能都能满足,源码简单易懂,可以随意二开,封装度非常高,不理解原理的就很容易变成工具人了,其他的等用一段时间再评论。
参考:
http://sa-token.dev33.cn/
https://github.com/dromara/sa-token
当前标题:从零搭建开发脚手架集成认证授权Sa-Token(尝鲜)
转载来于:http://www.shufengxianlan.com/qtweb/news4/335704.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联