本项目采用权限认证框架sa-tokensa-token-solon-plugin

pom.xml

<!--        鉴权-->
<dependency>
<groupId>org.noear</groupId>
<artifactId>sa-token-solon-plugin</artifactId>
</dependency>

配置

# sa-token配置
sa-token:
# token名称 (同时也是cookie名称)
token-name: xrilang-api-token
# token有效期,单位s 默认30天, -1代表永不过期
timeout: 2592000
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
activity-timeout: -1
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
allow-concurrent-login: true
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
is-share: true
# token风格
token-style: uuid
# 是否输出操作日志
is-log: false

app.yml配置sa-token

登录认证

登录成功

相关资料:登录认证 (sa-token.cc)

首先是登录,登录成功了,调用StpUtil.login()方法,保存用户ID

该方法会自动生成token、token有效期等信息,和用户ID一起保存在Cookie当中

大致就是如上图这样的一些信息。

登录认证相关接口

这些方法官方文档有介绍,写成接口方便查询和操作。比如退出登录、查询token信息等等。


// 查询登录状态,浏览器访问: http://localhost:9420/sign/isLogin
@Mapping("/isLogin")
public String isLogin() {
return "当前会话是否登录:" + StpUtil.isLogin();
} /**
* 获取登录用户的id
* @return String
*/
@Mapping("/loginId")
public String loginId() {
return StpUtil.getLoginIdAsString();
} /**
* 获取登录用户的token
* @return String
*/
@Mapping("/loginToken")
public String loginToken() {
return StpUtil.getTokenValue();
} /**
* 退出登录
* @return String
*/
@Mapping("/logout")
public String isLogout() {
;
StpUtil.logout();
return loginId()+"退出登录";
} @Mapping("/token_timeout")
public Long getTokenTimeout(String account) {
return StpUtil.getTokenTimeout();
} /**
* 获取当前会话的 token 信息参数
* return
*/
@Mapping("/tokenInfo")
public SaTokenInfo getTokenInfo() {
return StpUtil.getTokenInfo();
}

路由拦截

相关参考资料:路由拦截鉴权 (sa-token.cc)

sa-token-solon-plugin和sa-token的写法可能会有一点区别。

这里使用的是sa-token-solon-plugin

首先注解是@Configuration

package cc.mllt.xrilang.WebConfig;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.solon.integration.SaTokenInterceptor;
import cn.dev33.satoken.stp.StpUtil;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.Filter;
import org.noear.solon.core.handle.FilterChain;
import org.smartboot.http.common.logging.Logger;
import org.smartboot.http.common.logging.LoggerFactory; @Configuration
public class AppFilter implements Filter { private static final Logger log = LoggerFactory.getLogger(AppFilter.class); @Bean
public SaTokenInterceptor saTokenInterceptor() {
return new SaTokenInterceptor()
.addInclude("/**/**")
.addExclude("/favicon.ico")
.addExclude("/sign/**")
.setAuth(req -> {
SaRouter.match("/**", StpUtil::checkLogin)
.match("/user/**", r -> StpUtil.checkPermission("user"))
.match("/admin/**", r -> StpUtil.checkPermission("admin"));
})
.setError(e -> {
log.error("未登录的非法请求。"+e.getMessage());
return "未登录";
})
.setBeforeAuth(req -> {
SaHolder.getResponse()
.setServer("xrilang-api-server")
.setHeader("X-Frame-Options", "SAMEORIGIN")
.setHeader("X-XSS-Protection", "1; mode=block")
.setHeader("X-Content-Type-Options", "nosniff");
});
} @Override
public void doFilter(Context ctx, FilterChain chain) throws Throwable {
long start = System.currentTimeMillis();
try {
chain.doFilter(ctx);
if (!ctx.getHandled()) {
ctx.status(404);
ctx.output("Resource not found.");
}
} catch (Throwable e) {
ctx.status(500);
ctx.output(e.getMessage());
// 错误已经被 `setError` 方法记录,这里不再重复记录
}
long timeTaken = System.currentTimeMillis() - start;
log.info("Request processed in {} ms", timeTaken);
}
}

关键的地方在于

    public SaTokenInterceptor saTokenInterceptor() {
return new SaTokenInterceptor()
.addInclude("/**/**")
.addExclude("/favicon.ico")
.addExclude("/sign/**")
.setAuth(req -> {
SaRouter.match("/**", StpUtil::checkLogin)
.match("/user/**", r -> StpUtil.checkPermission("user"))
.match("/admin/**", r -> StpUtil.checkPermission("admin"));
})
.setError(e -> {
log.error("未登录的非法请求。"+e.getMessage());
return "未登录";
})
.setBeforeAuth(req -> {
SaHolder.getResponse()
.setServer("xrilang-api-server")
.setHeader("X-Frame-Options", "SAMEORIGIN")
.setHeader("X-XSS-Protection", "1; mode=block")
.setHeader("X-Content-Type-Options", "nosniff");
});
}

这个方法无需被调用。

配置好放行哪些,不放行哪些,错误返回信息就行。

Session会话

相关资料:Session会话 (sa-token.cc)

具体使用方法以后再更新。

集成redis

参考资料:集成 Redis (sa-token.cc)

这里使用官方文档的第二种方式集成redis

所有pom.xml现在是

<!--        鉴权-->
<dependency>
<groupId>org.noear</groupId>
<artifactId>sa-token-solon-plugin</artifactId>
</dependency>
<!--鉴权-redis-序列化-->
<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
<version> 1.38.0</version>
</dependency>
<!-- Jackson 的 JSR310 支持模块 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version> 2.17.2</version>
</dependency>
<!-- 提供Redis连接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version> 2.11.1</version>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version> 3.21.3</version>
</dependency>

然后配置redis连接信息

集成 Redis 后,是我额外手动保存数据,还是框架自动保存?

框架自动保存。集成 Redis 只需要引入对应的 pom依赖 即可,框架所有上层 API 保持不变。

我是创建了一个RedisConfig.java文件,代码如下

package cc.mllt.xrilang.WebConfig;

import cn.dev33.satoken.dao.SaTokenDao;
import cn.dev33.satoken.solon.dao.SaTokenDaoOfRedissonJackson;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
import org.smartboot.http.common.logging.Logger;
import org.smartboot.http.common.logging.LoggerFactory; @Configuration
public class RedisConfig {
static Logger log = LoggerFactory.getLogger(RedisConfig.class); @Inject(value="${redis.host}", autoRefreshed = true)
private String host; @Inject(value="${redis.port}", autoRefreshed = true)
private int port; // @Inject(value="${redis.password}", autoRefreshed = true)
// private String password; @Bean
public RedissonClient redissonClient() {
try {
Config config = new Config();
config.useSingleServer()
.setAddress("redis://" + host + ":" + port)
.setDatabase(1); // 使用配置中的数据库索引
// .setPassword(password);
RedissonClient redisson = Redisson.create(config);
log.info("连接redis成功");
return redisson;
}catch (Exception e){
log.error("连接redis失败,请检查Redis配置信息并先启动redis", e);
return null;
}
} @Bean
public SaTokenDao saTokenDao(RedissonClient redissonClient) {
return new SaTokenDaoOfRedissonJackson(redissonClient);
}
}

[solon]Solon开发实战之权限认证的更多相关文章

  1. Django 中使用权限认证

    权限认证 权限概念 """ 在实际开发中,项目中都有后台运营站点,运营站点里面会存在多个管理员, 那么不同的管理员会具备不同的任务和能力,那么要实现这样的管理员功能,那么 ...

  2. Solon Web 开发,七、视图模板与Mvc注解

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  3. thinkphp5的Auth权限认证实战

    thinkphp5的Auth权限认证实战 一.总结 一句话总结:基于角色的权限管理(真正做一遍,就会发现很简单,不然一直都是半懂不懂的) 角色 权限 真正做一遍,就会发现很简单,不然一直都是半懂不懂的 ...

  4. Hangfire实战二——为DashBoard页面添加权限认证

    概述 Hangfire Dashboard为我们提供了可视化的对后台任务进行管理的界面,我们可以直接在这个页面上对定时任务进行删除.立即执行等操作,如下图所示: 默认情况下,这个页面只能在部署Hang ...

  5. Solon Web 开发

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  6. Solon Web 开发,一、开始

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  7. Solon Web 开发,二、开发知识准备

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  8. Solon Web 开发,四、请求上下文

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  9. Solon Web 开发,五、数据访问、事务与缓存应用

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  10. Solon Web 开发,六、过滤器、处理、拦截器

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

随机推荐

  1. FB 汉化版恢复慢速更新

    汉化版将恢复慢速更新 -------------------------[Q群]------------------------ 1 群: 11675361 2 群: 47642719 ------- ...

  2. Nuxt.js 应用中的 link:prefetch 钩子详解

    title: Nuxt.js 应用中的 link:prefetch 钩子详解 date: 2024/10/7 updated: 2024/10/7 author: cmdragon excerpt: ...

  3. 树莓派2 CentOS7.9 安装配置笔记

    1. 镜像下载与安装 http://isoredirect.centos.org/altarch/7/isos/armhfp/找到https://mirrors.tuna.tsinghua.edu.c ...

  4. python处理nii文件

    第一步安装nibabel,可以使用命令:pip install nibabel 之后: from nibabel.viewers import OrthoSlicer3D as osdimport n ...

  5. 技术分享PPT整理(三):网页渲染流程

    在我刚开始学习Web开发的时候,一直有个疑问--我写出的代码究竟是在什么时候发生作用的呢?是不是每次我修改代码网页都随之变化了?当然,现在来看这肯定是一个错误的想法,经过一段时间的工作和学习后,代码到 ...

  6. Spring 实现 3 种异步流式接口,干掉接口超时烦恼

    大家好,我是小富- 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable.WebAsyncTask 和 DeferredResult.CompletableFuture等均可实现 ...

  7. vivo 轩辕文件系统:AI 计算平台存储性能优化实践

    在早期阶段,vivo AI 计算平台使用 GlusterFS 作为底层存储基座.随着数据规模的扩大和多种业务场景的接入,开始出现性能.维护等问题.为此,vivo 转而采用了自研的轩辕文件系统,该系统是 ...

  8. mosquitto(MQTT)服务器搭建和基本使用

    一.安装 搭建一个mqtt服务器,这里我们采用mosquitto 1. 下载地址:https://mosquitto.org/download/ 2. 选择windows:https://mosqui ...

  9. 基于Java+SpringBoot心理测评心理测试系统功能实现三

    一.前言介绍: 1.1 项目摘要 心理测评和心理测试系统在当代社会中扮演着越来越重要的角色.随着心理健康问题日益受到重视,心理测评和心理测试系统作为评估个体心理状态.诊断心理问题.制定心理治疗方案的工 ...

  10. .NET周刊【11月第2期 2024-11-10】

    国内文章 .NET 全能高效的 CMS 内容管理系统 https://www.cnblogs.com/1312mn/p/18511224 SSCMS 是一个完全开源的企业级内容管理系统,基于 .NET ...