探索 Sa-Token (二) 登录认证、权限认证

news/2024/5/7 1:11:00/文章来源:https://blog.csdn.net/weixin_38982591/article/details/126765804

(一)登录认证

  说明:因为这里没有连接数据,我模拟两个用户,用户:zhang ,用户:liu,密码 123456 提前做了加密。

1.密码加密接口

/*** 加密* @param pwd* @return*/@GetMapping("/register")public SaResult register(String pwd) {// 注册用户String hashpw = BCrypt.hashpw(pwd);return SaResult.data(hashpw);}

2. 模拟数据库用户信息

 /*** 模拟数据库用户信息** @param name* @return*/private LoginUser builderLoginUser(String name) {String dbPwd = "$2a$10$roWr2BV2LcMrGFo2ST.vluO4DkwLVt5LhozZGP4OKz3.eh31lAJ6q";Set<String> perms = new HashSet<String>();LoginUser loginUser = new LoginUser();loginUser.setPwd(dbPwd);loginUser.setName(name);if ("zhang".equals(name)) {perms.add("*.*.*");loginUser.setId(10001);loginUser.setMenuPermission(perms);} else if ("liu".equals(name)){perms.add("web:test:user");loginUser.setId(10002);loginUser.setMenuPermission(perms);}return loginUser;}

3.登录接口

 /*** 登录** @param name* @param pwd* @return*/@GetMapping("/doLogin")public SaResult doLogin(String name, String pwd) {LoginUser loginUser = builderLoginUser(name);boolean checkpw = BCrypt.checkpw(pwd, loginUser.getPwd());// 第一步:比对前端提交的账号名称、密码if (checkpw) {// 第二步:根据账号id,进行登录,指定设备类型StpUtil.login(loginUser.getId(), DeviceType.PC.getDevice());StpUtil.getTokenSession().set(LOGIN_USER_KEY, loginUser);return SaResult.data(StpUtil.getTokenInfo());}return SaResult.error("登录失败");}

这里为了做简单测试就不做其它等校验。

StpUtil.login(用户ID,设备类型)  

#test#result

 

 登录成功之后尝试,用token访问下其他接口

 登录认证成功。

(二)权限认证

所谓权限认证,核心逻辑就是判断一个账号是否拥有指定权限:

  • 有,就让你通过。
  • 没有?那么禁止访问!

深入到底层数据中,就是每个账号都会拥有一个权限码集合,框架来校验这个集合中是否包含指定的权限码。

例如:当前账号拥有权限码集合 ["user-add", "user-delete", "user-get"],这时候我来校验权限 "user-update",则其结果就是:验证失败,禁止访问

1. 自定义SaPermissionImpl 实现StpInterface 接口

@Component
public class SaPermissionImpl implements StpInterface {/*** 获取菜单权限列表*/@Overridepublic List<String> getPermissionList(Object loginId, String loginType) {// 当用户调用权限验证的时候走LoginUser loginUser = getLoginUser();// 返回当前登录用户拥有的菜单集合return new ArrayList<>(loginUser.getMenuPermission());}private  LoginUser getLoginUser() {return  (LoginUser) StpUtil.getTokenSession().get(LOGIN_USER_KEY);}/*** 获取角色权限列表*/@Overridepublic List<String> getRoleList(Object loginId, String loginType) {return null;}
}

说明:前面模拟两个用户,zhang ,权限集合["*.*.*"] 表示超级管理员,啥接口都能访问,liu 是普通用户,权限集合["web:test:user"]

新建两个测试接口:

   @SaCheckPermission("web:test:user")@GetMapping("/getLoginUser")public SaResult getLoginUser() {Object loginId = StpUtil.getLoginId();System.out.println("接口[getLoginUser]当前用户:" + loginId);return SaResult.data(loginId);}@SaCheckPermission("web:test:testPerms")@GetMapping("/testPerms")public SaResult testPerms() {Object loginId = StpUtil.getLoginId();System.out.println("接口[testPerms]当前用户:" + loginId);return SaResult.data(loginId);}

可以看到用户liu是没有第二个接口的权限的。

#test#result

 用户zhang两个接口都这可以正常访问。

 用户liu没有第二个接口的权限,测试结果成功。

### 这里输出的log其实是做了全局异常的捕获。

#GlobalExceptionHandler

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.http.HttpStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;import javax.servlet.http.HttpServletRequest;/*** @author yueF_L* @version 1.0* @date 2022-09-07 11:20* 全局异常处理*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {/*** 认证失败*/@ExceptionHandler(NotLoginException.class)public SaResult handleNotLoginException(NotLoginException e, HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',认证失败'{}',无法访问系统资源", requestURI, e.getMessage());return SaResult.get(HttpStatus.HTTP_UNAUTHORIZED, "认证失败,无法访问系统资源", null);}/*** 权限码异常*/@ExceptionHandler(NotPermissionException.class)public SaResult handleNotPermissionException(NotPermissionException e, HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',权限码校验失败'{}'", requestURI, e.getMessage());return SaResult.get(HttpStatus.HTTP_FORBIDDEN, "没有访问权限,请联系管理员授权",null);}}

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统优化 : 笔记本盖上休眠

如何使休眠可用按下键盘上的 Windows 按钮,打开开始菜单或开始屏幕。 搜索“cmd”。 在搜索结果中,右键单击“命令提示符”,然后选择“以管理员身份运行”。 当用户帐户控制提示时,选择“继续”。 在命令提示符处,键入 powercfg.exe /hibernate on,然后按 Enter。 键入“…

MySQL复制

环境条件master:192.168.247.20 rocky8.6 mysql8.0.26 slave: 192.168.247.21 rocky8.6 mysql8.0.26基本环境准备 hostnamectl set-hostname mysql-master-01 hostnamectl set-hostname mysql-slave-01主从安装mysql-server服务 yum -y install mysql-server systemctl enabl…

3、计算机系统漫游

目录1 计算机的信息2 编译系统3 编译系统4 高速缓存5 存储器层次结构6 操作系统6.1 操作系统的抽象表示6.2 进程 1 计算机的信息信息:就是位+上下文 系统中所有的信息,包括磁盘文件、内存中的程序,内存中存放的用户数据,以及网络上传输的数据,都是由一串0、1表示 位:指8位…

vue3项目-小兔鲜儿笔记-购物车02

1.购物车页面-列表展示-本地准备已选择的商品列表数据,已选择的商品件数以及需要支付的金额渲染模板// 有效商品列表 validList(state) {return state.list.filter((goods) => goods.isEffective && goods.stock > 0) }, // 有效商品件数 validTotal() {return …

django框架八

批量操作数据 自定义分页器(重在思路) form组件 modelform组件 cookie与session简介批量操作数据 浏览器访问一个django路由 立刻创建10万条数据并展示到前端页面create()、all() 涉及到大批量数据的创建 直接使用create可能会造成数据库崩溃批量数据创建>>>:bulk_cre…

07- 诊断事件diagnostic events的类图关系

文章目录 1 DEM模块的诊断事件diagnostic events的类图关系2 各个参数的含义介绍1 DEM模块的诊断事件diagnostic events的类图关系 这个时DEM模块的诊断事件diagnostic events的类图关系。 关于其在Davinci中的体现,请参考【06- 诊断事件DemEventParameter的配置】文章的介绍…

【日常】edge和chrome浏览器截屏工具快捷键

首先打开开发者工具 使用右键===>检查 就能打开开发者模式 在开发者模式下,快捷键ctrl+shift + p然后输入截屏,就能看到了 开源作品 GOFLY是一款基于Golang+Vue开发的在线客服系统,软件著作权编号:2021SR1462600。一套可私有化部署的在线客服系统,编译后的二进制文件可…

mysql在移机后的机器上配置(该机器重装了操作系统)

说明一切就绪后,唯有mysql没起来 连接本地数据库,mysql提示Can‘t connect to MySQL server on localhost (10061)解决办法_Geeca的博客-CSDN博客 https://blog.csdn.net/Geeca/article/details/125924886 本地无法启动MySQL服务,报的错误:1067,进程意外终止---解决_java奋…

PowerShell中异步方法的使用

问题 PowerShell脚本中有个文件上传功能,使用HttpClient 脱敏处理后基本就是这样子 $client = new-object System.Net.Http.HttpClient; $result = $client.PostAsync($URL,@{}).Result;别问为什么不用await,问就是有原因某天程序执行后,$result始终为空,也无异常 经过艰苦卓…

html对象常用属性和Window 对象属性

​/* *作者:呆萌老师 *☑csdn认证讲师 *☑51cto高级讲师 *☑腾讯课堂认证讲师 *☑网易云课堂认证讲师 *☑华为开发者学堂认证讲师 *☑爱奇艺千人名师计划成员 *在这里给大家分享技术、知识和生活 *各种干货,记得关注哦! *vx:it_daimeng */ html对象常用属性 取值赋值:inn…

Javaweb学习笔记第四弹

JDBC API详解 1、DriverManager作用: 1、注册驱动 registerDriver 2、获取数据库连接 getConnection 参数:1、url jdbc:mysql://localhost:3306/数据库名称 ​ 2、user 用户名 ​ 3、password 密码 注意:在url中,如果连接的是本机,并且…

Educational Codeforces Round 132 (Rated for Div. 2) A.B.D

A. Three Doors 题目链接&#xff1a; Problem - A - Codeforces 题面&#xff1a; 题意&#xff1a; 共有三扇门&#xff0c;一开始你有一把钥匙&#xff0c;有两扇门后面有钥匙&#xff0c;一扇门后面没有钥匙&#xff08;如果有钥匙&#xff0c;就会告诉你可以开哪扇门&am…

【Servlet】这一文详细的讲述了Servlet的知识,呕心沥血,终于文成。

文章目录什么是Servlet&#xff1f;Servlet的使用1、创建一个Web项目&#xff0c;并集成Tomcat2、引入Servlet的依赖3、创建一个Web启动类第一个是重写Servlet接口第二个是继承HttpServletServlet的理解Servlet的执行流程Servlet的生命周期加载和实例化阶段初始化阶段请求处理服…

202112-2 CCF 序列查询新解 (枚举 + 分段讨论 满分题解)

问题描述 序列查询新解 题目链接 解题思路 这个是上一道题目总结出来的规律 就是 f(x) i 当x属于 【a[i], a[i 1] &#xff09; 这个区间 也就是在这个区间里f(x)都等于一个数i 再看g(x)这个函数&#xff0c;g(x&#xff09; x / 常数&#xff0c;也可以知道&#xff0c;g…

微服务技术初探(go-micro)

微服务技术初探 微服务概述 微服务是近几年产生的新概念,与传统的单体式服务相比,微服务具有更好的扩展性及低耦合度等特性。微服务的重点在于服务的治理和调度。 微(micro):狭义来说就是体积小。 服务(service):区别于系统,服务一个或者一组相对较小且独立的功能单元,是…

c语言实现通讯录

目录标题通讯录的介绍通讯录的准备通讯录的初始化通讯录的添加通讯录的打印通讯录的查找并打印通讯录的删除通讯录的排序通讯录的修改通讯录的改善动态通讯录的实现以文件的形式存储通讯录的介绍 通讯录想必大家都应该不陌生&#xff0c;我们在手机里面都会有通讯录里面记录着…

爬虫数据可视化前的环境准备(已安装python环境前提下)

一、requests请求库安装 在桌面右键打开终端输入:pip install requests 二、Beautiful Soup解析库安装 终端输入:Beautiful Soup 4安装:pip install bs4 lxml安装:pip install lxml三、matplotlib安装下载miniconda下载地址:https://docs.conda.io/en/latest/miniconda.ht…

CF102411 ICPC 2019-2020 North-Western Russia Regional Contest题解

A Accurate Movement 签到 M Managing Difficulties 签到 B Bad Treap 已知\(y=\sin(x)\),要求给出数组\(a[n]\),满足\(\forall i,j\in[1,n],a[i]\neq a[j]\),都有\(\sin(a[i])\neq \sin(a[j])\)。 这里又一种不怎么玄的写法,就是我们找到一个整数\(x\),\(sin(x)\)非常非常…

计算机的概述

计算机是由硬件系统(hardware system)和软件系统(software system)两部分组成的。硬件系统电源电源是电脑中不可缺少的供电设备,它的作用是将220V交流电转换为电脑中使用的5V、12V、3.3V直流电,其性能的好坏,直接影响到电脑其他设备工作的稳定性,进而会影响整机的稳定性…

AXI MCDMA 仿真与工作流程分析

说明 关于背景知识,可以先看 https://www.cnblogs.com/xingce/p/16386108.html 引用一段官方的说明,AXI MCDMA存在的主要目的是为了节约资源,我们想要使用这个模块的主要目的也是为了降低资源消耗,从而可以将系统部署在更小面积的FPGA芯片上,当然,具体的效果还需要进一步…