认证鉴权框架之—sa-token

news2024/12/23 10:53:25

一、概述

Satoken 是一个 Java 实现的权限认证框架,它主要用于 Web 应用程序的权限控制。Satoken 提供了丰富的功能来简化权限管理的过程,使得开发者可以更加专注于业务逻辑的开发。

二、逻辑流程

1、登录认证
(1)、创建token
当用户输入用户名和密码请求登录,后端验证用户名和密码的正确性。验证成功时,调用sa-token提供的登录接口,创建token

StpUtil.login(saBaseLoginUser.getId(), new SaLoginModel().setDevice(device).setExtra("name", saBaseLoginUser.getName()));

此方法,会自动创建token,并将token和会话session相关联,并且返回给前端的响应头中自动设置token:如下:
Response Header中返回set-cookie:token=token值
在这里插入图片描述
浏览器接受response后,会自动设置token的请求头,之后请求该域的接口时,会自动带上该请求头
Request Header中会携带token
在这里插入图片描述
如上的创建token,到给前端设置token的过程,只需要后端调用sa-token的登录接口,其他无需我们做任何事情。

(2)、创建当前用户的缓存
当调用完成sa-token的登录接口后,我们可以构建当前登录用户的对象SaBaseLoginUser,该对象可以添加权限,角色,组织等信息。
设置到sa-token的缓存中,这样在之后的接口中,我们需要获取当前用户信息或当前用户信息的权限等信息时,就可以直接从sa-token缓存中获取,就无需从数据库中再次查询。

设置当前用户的缓存
StpUtil.getTokenSession().set("loginUser", saBaseLoginUser);
获取当前用户的缓存
Object loginUser = StpUtil.getTokenSession().get("loginUser");
if (ObjectUtil.isNull(loginUser)) throw new CommonException("用户未登录");
SaBaseLoginUser saBaseLoginUser = (SaBaseLoginUser) loginUser;

注意,这里我们最好整合redis使用,否则会占用系统内存,占用内存多了就会造成性能瓶颈问题。同时整合redis也可以适用分布式多节点的服务。

2、查询权限(菜单和接口)
(1)、菜单权限
关于菜单,针对每一个前端页面的路由创建不同的菜单数据保存到数据库就行,之后针对角色进行授权即可。方法比较常见不在赘述。

(2)、接口权限
关于接口权限,sa-token自带一些注解类去管理接口权限,如:在controller类上使用@SaCheckRole注解或接口上使用@SaCheckPermission注解,标识该类或者接口为待认证的接口。

在spring容器初始化时,会初始化和注入所有的接口到容器中被spring所管理,可以通过springApplication上下文对象获取所有的RequestMappingHandlerMapping.class,即所有的controller类。在分别requestMappingHandlerMapping.getHandlerMethods()方法,即查询了所有的接口。
示例代码:

SpringUtil.getApplicationContext().getBeansOfType(RequestMappingHandlerMapping.class).values()
                .forEach(requestMappingHandlerMapping -> requestMappingHandlerMapping.getHandlerMethods()
                        .forEach((key, value) -> {
                            SaCheckPermission saCheckPermission = value.getMethod().getAnnotation(SaCheckPermission.class);
                            if (ObjectUtil.isNotEmpty(saCheckPermission)) {
                                PatternsRequestCondition patternsCondition = key.getPatternsCondition();
                                if (patternsCondition != null) {
                                    String apiName = "未定义接口名称";
                                    ApiOperation apiOperation = value.getMethod().getAnnotation(ApiOperation.class);
                                    if (ObjectUtil.isNotEmpty(apiOperation)) {
                                        String annotationValue = apiOperation.value();
                                        if (ObjectUtil.isNotEmpty(annotationValue)) {
                                            apiName = annotationValue;
                                        }
                                    }
permissionResult.add(patternsCondition.getPatterns().iterator().next() + StrUtil.BRACKET_START + apiName + StrUtil.BRACKET_END);
                                }
                            }
                        }));

3、授权
(1)、菜单授权
从数据库中查询所有的菜单数据,直接授权给角色即可。
(2)、接口授权
通过如上的方法,查询所有的接口权限(可以在容器初始化时保存到缓存中,减少查询次数)。之后做成表单,授权给角色或者指定账号即可。
在这里插入图片描述
4、鉴权
sa-token拦截器(SaInterceptor),我们只需要将拦截器注册到spring容器中,拦截所有的请求进行校验。

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册注解拦截器,并排除不需要注解鉴权的接口地址 (与登录拦截器无关,只是说明哪些接口不需要被拦截器拦截,此处都拦截)
        registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
    }

sa-token会开放查询用户权限和角色的接口给我们重写,我们只需要覆写(自定义类实现StpInteface接口,覆写里面的方法)获取用户权限和角色的接口即可。
在这里插入图片描述
5、总结
如上,我们描述了一个完整示例。从创建token,前端在指定域内请求携带token。在到获取权限,授权和鉴权的全过程。授权信息一般可以保存到数据库中,通过sa-token官方的示例去覆写接口即可。其他只需要我们在合适的类上或者接口上添加注解就行。

三、代码示例
1、引入依赖
如果服务只有一个节点,仅配置第一个sa-token-spring-boot-starter就够用了,后两个依赖是将redis和sa-token整合,这样认证信息保存到redis中,跨节点权限认证时也不会出现问题。

<!--版本-->
<properties>
    <sa.token.version>1.31.0</sa.token.version>
</properties>

<!-- sa-token -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-spring-boot-starter</artifactId>
    <version>${sa.token.version}</version>
</dependency>

<!-- sa-token 整合 redis (使用jackson序列化方式) -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-dao-redis-jackson</artifactId>
    <version>${sa.token.version}</version>
</dependency>

<!-- Sa-Token插件:权限缓存与业务缓存分离 -->
<dependency>
    <groupId>cn.dev33</groupId>
    <artifactId>sa-token-alone-redis</artifactId>
    <version>${sa.token.version}</version>
</dependency>

2、配置文件

#########################################
# redis configuration
#########################################
spring:
  redis:
    database: 0
    host: 172.xx.xxx.xx
    port: 6379
    password:
    timeout: 10s
    lettuce:
      pool:
        max-active: 200       // 连接池最大连接数
        max-wait: -1ms       // 连接池最大阻塞等待时间(负数表示不限制)
        max-idle: 10          // 连接池中最大空闲连接
        min-idle: 0           // 连接池中最小空闲连接
#########################################
# sa-token configuration
#########################################
sa-token:
  token-name: token     // token名称,即设置cookie的key值
  timeout: 2592000      // token有效期(秒),默认30天,-1代表永久有效
  activity-timeout: -1     // 最低活跃频率(秒),即超过这个时间没有访问系统会冻结该token,默认-1代表永不冻结
  is-concurrent: true    // 是否允许同一账号多地登录
  is-share: false      // 是否同一账号多地登录时共用同一个token
  max-login-count: -1
  token-style: random-32
  is-log: false     // 是否输出操作日志
  is-print: false

# sa-token alone-redis configuration
  alone-redis:
    database: 2    // 指定sa-token使用redis的哪一个库
    host: ${spring.redis.host}
    port: ${spring.redis.port}
    password: ${spring.redis.password}
    timeout: ${spring.redis.timeout}
    lettuce:
      pool:
        max-active: ${spring.redis.lettuce.pool.max-active}
        max-wait: ${spring.redis.lettuce.pool.max-wait}
        max-idle: ${spring.redis.lettuce.pool.max-idle}
        min-idle: ${spring.redis.lettuce.pool.min-idle}

如上配置的sa-token整合redis后,sa-token在创建token信息时,会自动将token信息保存到配置的redis中,无需我们在操作redis进行设置。
在这里插入图片描述
3、全局管理类
这里我们注册sa-token拦截器,注入StpLogic管理类(一般多种用户类型时需要),重写注解合并方法(父类有的注解也会被作用到子类处理),覆写sa-token的自定义接口查询用户角色和权限。

import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.stp.StpInterface;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.strategy.SaStrategy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import cn.nivic.common.auth.enums.SaClientTypeEnum;
import cn.nivic.common.auth.util.StpClientLoginUserUtil;
import cn.nivic.common.auth.util.StpLoginUserUtil;
import java.util.List;

/**
 * SaToken鉴权配置
 **/
@Configuration
public class AuthConfigure implements WebMvcConfigurer {

    /**
     * 注册Sa-Token的注解拦截器,打开注解式鉴权功能
     *
     * 注解的方式有以下几中,注解既可以加在接口方法上,也可加在Controller类上:
     * 1.@SaCheckLogin: 登录认证 —— 只有登录之后才能进入该方法(常用)
     * 2.@SaCheckRole("admin"): 角色认证 —— 必须具有指定角色标识才能进入该方法(常用)
     * 3.@SaCheckPermission("user:add"): 权限认证 —— 必须具有指定权限才能进入该方法(常用)
     * 4.@SaCheckSafe: 二级认证校验 —— 必须二级认证之后才能进入该方法
     * 5.@SaCheckBasic: HttpBasic认证 —— 只有通过 Basic 认证后才能进入该方法
     *
     * 在Controller中创建一个接口,默认不需要登录也不需要任何权限都可以访问的,只有加了上述注解才会校验
     **/
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册注解拦截器,并排除不需要注解鉴权的接口地址 (与登录拦截器无关,只是说明哪些接口不需要被拦截器拦截,此处都拦截)
        registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
    }

    @Bean("stpLogic")
    public StpLogic getStpLogic() {
        // 注入Sa-Token的StpLogic,客户端类型为B,处理B端用户的权限管理
        return new StpLogic(SaClientTypeEnum.B.getValue());
    }

    @Bean("stpClientLogic")
    public StpLogic getStpClientLogic() {
        // 注入Sa-Token的StpLogic,客户端类型为C,处理C端用户的权限管理        		return new StpLogic(SaClientTypeEnum.C.getValue());
    }

    @Bean
    public void rewriteSaStrategy() {
        // 重写Sa-Token的注解处理器,增加注解合并功能
// 这里的注解合并,即在继承体系中,也能获取到父类的注解实例。
        SaStrategy.me.getAnnotation = AnnotatedElementUtils::getMergedAnnotation;
    }

    /**
     * 权限认证接口实现类,集成权限认证功能
* 重写sa-token获取权限的接口,这里用户更具业务编码从数据库或者mongoDb中获取权限
     **/
    @Component
    public static class StpInterfaceImpl implements StpInterface {

        /**
         * 返回一个账号所拥有的权限码集合
         */
        @Override
        public List<String> getPermissionList(Object loginId, String loginType) {
            if (SaClientTypeEnum.B.getValue().equals(loginType)) {
                return StpLoginUserUtil.getLoginUser().getPermissionCodeList();
            } else {
                return StpClientLoginUserUtil.getClientLoginUser().getPermissionCodeList();
            }
        }

        /**
         * 返回一个账号所拥有的角色标识集合
         */
        @Override
        public List<String> getRoleList(Object loginId, String loginType) {
            if (SaClientTypeEnum.B.getValue().equals(loginType)) {
                return StpLoginUserUtil.getLoginUser().getRoleCodeList();
            } else {
                return StpClientLoginUserUtil.getClientLoginUser().getRoleCodeList();
            }
        }
    }

}

4、注解和使用
(1)、@SaCheckLogin
放在controller的接口方法上,在调用到这个方法的时候,会校验用户是否登录,如果没有登录会直接报错,保障安全。一般放在关键接口上,一般接口无需如此。

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.validation.Valid;

@Api(tags = "B端登录控制器")
@RestController
@Validated
public class AuthController {

    /**
     * B端退出
     **/
    @ApiOperationSupport(order = 5)
    @ApiOperation("B端退出")
    @SaCheckLogin
    @GetMapping("/auth/b/doLogout")
    public CommonResult<String> doLogout() {
        StpUtil.logout();
        return CommonResult.ok();
    }

    /**
     * B端获取用户信息
     **/
    @ApiOperationSupport(order = 6)
    @ApiOperation("B端获取用户信息")
    @SaCheckLogin
    @GetMapping("/auth/b/getLoginUser")
    public CommonResult<SaBaseLoginUser> getLoginUser() {
        return CommonResult.data(authService.getLoginUser());
    }
}

(2)、@SaCheckPermission
放在controller的接口方法上,用户请求到这个方法时,会校验用户是否有这个接口的权限,没有权限会直接报错。常用在数据增删改查接口上。
至于sa-token获取接口权限:则是通过全局配置类中实现StpInterfaceImpl接口,获取当前用户的全部权限。

 @ApiOperationSupport(order = 1)
    @ApiOperation("获取机构分页")
    @SaCheckPermission("/biz/org/page")
    @GetMapping("/biz/org/page")
    public CommonResult<Page<BizOrg>> page(BizOrgPageParam bizOrgPageParam) {
        return CommonResult.data(bizOrgService.page(bizOrgPageParam));
    }

(3)、@SaCheckRole
@SaCheckRole是sa-token校验角色权限的注解,这里自定义注解SaClientCheckRole,在注解类上添加@SaCheckRole注解,从而达到sa-token校验角色的效果之后,还可以继续扩展注解功能。
前提:我们在全部配置类中调整了注解处理器为注解合并方式,这样sa-token在解析注解SaClientCheckRole时也会读取父类的SaCheckRole注解,从而达到校验的效果。
至于sa-token获取角色:则是通过全局配置类中实现StpInterfaceImpl接口,获取当前用户的全部角色。

@SaCheckRole(type = StpClientUtil.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE})
public @interface SaClientCheckRole {

    /**
     * 需要校验的角色标识
     * @return 需要校验的角色标识
     */
    @AliasFor(annotation = SaCheckRole.class)
    String [] value() default {};

    /**
     * 验证模式:AND | OR,默认AND
     * @return 验证模式
     */
    @AliasFor(annotation = SaCheckRole.class)
    SaMode mode() default SaMode.AND;

}

四、sa-token基本组件
1、StpUtil
sa-token官方提供的工具类,提供了许多静态方法来帮助开发者快速地完成登录认证、权限校验等工作。例如,当用户登录时,可以通过 StpUtil.login(10001) 方法来标记当前会话已登录,并将账号ID写入会话中。设置当前用户信息缓存,可在之后的请求中获取登录用户信息等。具体实现还是依靠StpLogic完成的。

2、StpLogic
是 Sa-Token 框架的核心逻辑处理类,它封装了与认证和授权相关的具体实现。例如,当调用 StpUtil.logout() 方法时,实际上是调用了 StpLogic 的 logout 方法来处理会话注销的操作。此外,StpLogic 也用于实现登录、会话管理等核心逻辑。

3、StpInterface
是一个接口,它用于自定义权限认证的逻辑。开发者可以通过实现这个接口来提供自己的业务逻辑,比如实现 getPermissionList 方法来获取一个账号的所有权限列表,或者实现 getRoleList 方法来获取一个账号的角色列表。当 Sa-Token 需要校验权限时,它会调用这个接口的方法来获取相应的信息。

4、SaManager
一个管理类,它负责管理 Sa-Token 框架的各种全局组件,如全局配置 SaTokenConfig、持久化处理 SaTokenDao、权限认证 StpInterface、框架行为 SaTokenAction、上下文处理器 SaTokenContext 与 SaTokenSecondContext、认证活动监听 SaTokenListener、临时令牌验证 SaTempInterface、认证处理逻辑 StpLogic 等等。通过 SaManager,开发者可以方便地获取和管理这些组件。

5、SaStrategy
是一个策略类,它提供了一组策略方法,允许开发者自定义框架内部的一些行为。例如,你可以重写createToken方法来改变创建Token的策略,或者重写checkMethodAnnotation方法来改变如何校验一个Method 对象上的注解。

6、关联性
这些组件之间通过 SaManager 和 StpUtil 等工具类相互关联起来。例如,StpUtil 中的很多方法实际上都是调用了 StpLogic 的相应方法来实现其功能。而 StpLogic 在执行一些核心逻辑时,可能会调用 SaManager 中的组件,比如 SaTokenDao 来进行数据的持久化操作,或者调用 StpInterface 来获取权限信息。SaStrategy 则提供了一种机制,允许开发者在不改变 Sa-Token 框架核心逻辑的情况下调整某些行为。

7、流程图示例
StpUtil完成创建token,登录,登出等操作,具体通过StpLogic完成;
SaManager负责管理所有的Sa-token组件(StpLogic,StpInteface等…)
StpLogic负责实现所有的业务,会通过SaManager获取其他组件协调完成。
StpInterface给用户实现,提供具体的获取权限,角色等信息
SaStrategy指定策略,如注解合并等。
在这里插入图片描述

学海无涯苦作舟!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2231626.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python爬虫实现自动获取论文GB 7714引用

在写中文论文、本硕博毕业设计的时候要求非常严格的引用格式——GB 7714引用。对于普通学生来说都是在google scholar上获取&#xff0c;一个一个输入点击很麻烦&#xff0c;就想使用python完成这个自动化流程&#xff0c;实现批量的倒入论文标题&#xff0c;导出引用。 正常引…

pycharm中python控制台出现CommandNotFoundError: No command ‘conda run‘.

1、错误现象 pycharm中打开python控制台出现CommandNotFoundError: No command conda run.的错误。 2、背景 conda是4.6版本&#xff0c;在Anaconda Prompt可以正常运行虚拟环境。 3、解决方法 更新conda版本&#xff0c;基本命令&#xff0c;会自动更新到最新版本。 con…

masm汇编字符输入小写转大写演示

从键盘读取一个字符变成大写换行并输出 assume cs:codecode segmentstart:mov ah,1int 21hmov bl,alsub bl,20hmov dl,10mov ah,2int 21hmov dl,blmov ah,2int 21hmov ah,4chint 21hcode ends end start 效果演示&#xff1a;

VisualStudio远程编译调试linux_c++程序(二)

前章讲述了gdb相关&#xff0c;这章主要讲述用VisualStudio调试编译linux_c程序 1&#xff1a;环境 win10 VisualStudio 2022 Community ubuntu22.04 2:安装 1>vs安装时&#xff0c;勾选 使用c进行linux 和嵌入式开发 (这里以vs2022为例) OR VS安装好了&#xff0c; 选择工…

【002】基于SpringBoot+thymeleaf实现的蓝天幼儿园管理系统

基于SpringBootthymeleaf实现的蓝天幼儿园管理系统 文章目录 系统说明技术选型成果展示账号地址及其他说明源码获取 系统说明 基于SpringBootthymeleaf实现的蓝天幼儿园管理系统是为幼儿园提供的一套管理平台&#xff0c;可以提高幼儿园信息管理的准确性&#xff0c;系统将信息…

【AIGC】从CoT到BoT:AGI推理能力提升24%的技术变革如何驱动ChatGPT未来发展

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;迈向AGI的新跨越&#x1f4af;BoT与CoT的技术对比技术原理差异推理性能提升应用范围和通用性从错误中学习的能力总结 &#x1f4af;BoT的工作流程和机制初始化过程生成推…

无人机拦截捕获/直接摧毁算法详解!

一、无人机拦截捕获算法 网捕技术 原理&#xff1a;抛撒特殊设计的网具&#xff0c;捕获并固定无人机。 特点&#xff1a; 适用于小型无人机。 对无人机的损害较小&#xff0c;基本不影响其后续使用。 捕获成功率较高&#xff0c;且成本相对较低。 应用实例&#xff1a;…

解码层跑几次取决于输出词汇多少;10个单词,在解码层跑几次transformer

目录 解码层跑几次取决于输出词汇多少 10个单词,在解码层跑几次transformer 解码层跑几次取决于输出词汇多少 10个单词,在解码层跑几次transformer 取决于具体任务和输出要求 在自然语言处理任务中,Transformer 架构的解码器(Decoder)运行次数与你想要生成的输出长度有关…

算法【Java】—— 记忆化搜索

记忆化搜索 在前面我们已经学习了递归回溯等知识&#xff0c;什么是记忆化搜索&#xff0c;其实就是带着备忘录的递归&#xff0c;我们知道在递归过程中如果如果出现大量的重复的相同的子问题的时候&#xff0c;我们可能进行了多次递归&#xff0c;但是这些递归其实可以只用进…

优化EDM邮件营销,送达率与用户体验双赢

EDM邮件营销需选对平台&#xff0c;优化邮件列表&#xff0c;确保内容优质&#xff0c;进行邮件测试&#xff0c;关注用户反馈调整频率&#xff0c;以保高送达率&#xff0c;提升营销效果。 1. 了解电子邮件送达率的重要性 在开始优化邮件送达率之前&#xff0c;首先需要理解电…

Metasploit渗透测试之在云服务器中使用MSF

概述 随着云计算的发展&#xff0c;对基于云的应用程序、服务和基础设施的测试也在不断增加。在对云部署进行渗透测试时&#xff0c;最大的问题之一是共享所有权。过去&#xff0c;在进行渗透测试时&#xff0c;企业会拥有网络上的所有组件&#xff0c;我们可以对它们进行全部…

Qt桌面应用开发 第一天

目录 1.默认代码解析 1.1main.h解析 1.2myWidget.h解析 1.3FirstProject.pro解析&#xff08;FirstProject为创建的Qt项目名&#xff09; 2.命名规范与快捷键 3.按钮控件及窗口设置 3.1按钮控件QPushButton类 3.2窗口常用设计 4.Qt中的对象树 5.Qt中的坐标系 Qt是一个…

简记Vue3(三)—— ref、props、生命周期、hooks

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

Mybatis查询数据库,返回List集合,集合元素也是List。

#有时间需求会要求&#xff1a;查询全校的学生数据&#xff0c;且学生数据按班级划分。那么就需要List<List<user>>类型的数据。 SQL语句 SELECT JSON_ARRAYAGG(JSON_OBJECT(name , name ,BJMC, BJMC ,BJBH,BJBH)) as dev_user FROM dev_user WHERE project_id …

Freertos学习日志(1)-基础知识

目录 1.什么是Freertos&#xff1f; 2.为什么要学习RTOS&#xff1f; 3.Freertos多任务处理的原理 1.什么是Freertos&#xff1f; RTOS&#xff0c;即&#xff08;Real Time Operating System 实时操作系统&#xff09;&#xff0c;是一种体积小巧、确定性强的计算机操作系统…

批量提取当前文件夹内的文件名

在需要提取的文件夹内新建一个txt文件&#xff0c;输入&#xff1a; dir ./b>name.txt 然后将该txt文件的扩展名改为.bat 如图 双击即可提取当前文件夹文件名&#xff0c;并保存到name.txt内

小林渗透入门:burpsuite+proxifier抓取小程序流量

目录 前提&#xff1a; 代理&#xff1a; proxifier&#xff1a; 步骤&#xff1a; bp证书安装 bp设置代理端口&#xff1a; proxifier设置规则&#xff1a; proxifier应用规则&#xff1a; 结果&#xff1a; 前提&#xff1a; 在介绍这两个工具具体实现方法之前&#xff0…

Node.js:session JWT

Node.js&#xff1a;session & JWT sessioncookiesessionexpress-session JWTexpress-jwt & jsonwebtoken session HTTP协议是无状态的&#xff0c;客户端的每次HTTP请求都是独立的&#xff0c;多个请求之间没有直接的关系&#xff0c;服务器不会保留每次HTTP请求的状…

后台管理系统的通用权限解决方案(七)SpringBoot整合SpringEvent实现操作日志记录(基于注解和切面实现)

1 Spring Event框架 除了记录程序运行日志&#xff0c;在实际项目中一般还会记录操作日志&#xff0c;包括操作类型、操作时间、操作员、管理员IP、操作原因等等&#xff08;一般叫审计&#xff09;。 操作日志一般保存在数据库&#xff0c;方便管理员查询。通常的做法在每个…

曹操出行借助 ApsaraMQ for Kafka Serverless 提升效率,成本节省超 20%

本文整理于 2024 年云栖大会主题演讲《云消息队列 ApsaraMQ Serverless 演进》&#xff0c;杭州优行科技有限公司消息中间件负责人王智洋分享 ApsaraMQ for Kafka Serverless 助力曹操出行实现成本优化和效率提升的实践经验。 曹操出行&#xff1a;科技驱动共享出行未来 曹操…