本项目采用权限认证框架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. Java日期时间API系列34-----Jdk8中java.time包中的新的日期时间API类应用,使用Period一行代码计算生日。

    通过Java日期时间API系列9-----Jdk8中java.time包中的新的日期时间API类的Period和Duration的区别中得知,Period可以比较2个日期相差的年月日.年龄计算是2个日 ...

  2. 默认nginx.conf

    user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid ...

  3. python中字典的运算

    问题: 如何查找在两个字典中相同的键.值元素? dict1 = {'a': 1, 'b': 2, 'c': 3} dict2 = {'a': 10, 'y': 11,'b': 2} dict1.key ...

  4. RHEL 环境下 Subversion 服务器部署与配置

    RHEL 环境下 Subversion 服务器部署与配置 1. 更新系统 首先确保系统软件包是最新的: sudo yum update -y 2. 安装Apache和Subversion 2.1 安装 ...

  5. Ubuntu 22.04 全局快捷键失效问题

    安装完 Ubuntu 22.04 后,你有可能会发现系统的快捷键失效了.侧栏用 Win + x 选中程序不可用了.为各种应用程序设置的快捷键也不起作用了. 出现此现象的原因,是因为 Ubuntu 22 ...

  6. C语言数据类型和变量

    目录 1.数据类型介绍 1.1字符型 1.2整形 1.3浮点型 1.4布尔类型 1.5各种数据类型长度 1.5.1sizeof操作符 1.5.2数据类型长度 1.5.3 sizeof中表达式不计算 2 ...

  7. Tomcat弱口令上传war包

    Tomcat弱口令上传war包 思路:   利用弱口令登录管理页面 ---> 部署war包 ---> getshell 环境:   vulhub靶场:tomcat/tomcat8   启动 ...

  8. 技术前沿:AI大模型在自动化测试中的应用实例

    哈喽,大家好,我是六哥!今天咱们来聊一聊如何用AI大模型(比如GPT-3.5)来做自动化测试,别看这东西听起来高大上,但也没那么神,跟着我咱们一步一步来,保证你也能轻松搞定,学会了保准让你在工作中老省 ...

  9. Webshell流量分析之哥斯拉Godzilla&冰蝎Behinder

    目录 哥斯拉 冰蝎 哥斯拉和冰蝎相较于菜刀蚁剑,它们的通信流量是加密的,有比较好的抗检测能力. 菜刀和蚁剑流量分析:Webshell流量分析之菜刀Chopper&蚁剑AntSword 哥斯拉 ...

  10. 深入理解ReferenceQueue GC finalize Reference

    关于对象如何销毁以及finalize更详细的信息 目录 概述 1 先看一个对象finalize的顺序问题. 2 对象再生及finalize只能执行一次 3 SoftReference WeakRefe ...