【用户登录】模块之登录认证+鉴权业务逻辑
用户登录——⭐认证功能的流程图:
⭐鉴权流程图:
用户登录功能的Java代码实现
1. 实体类-User
orm框架:JPA
@Table(name = "user_tab")
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User implements Serializable {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)@Column(name="user_id")private Long id;@Column(name="user_name")private String username;@Column(name="user_password")private String password;@Column(name="user_phone")private String phone;@Column(name="user_nickname")private String nickname;@Column(name="user_create_by")private String createBy;@Column(name="user_create_time")private Date createTime;@Column(name="user_update_time")private Date updateTime;@Column(name="user_role_id")private Long roleId;
}
2. UserDao
@Repository
public interface UserDao extends JpaRepository<User,Long> {//根据user的username和password查询该用户User findByUsernameAndPassword(String username,String password);
}
3. UserService业务层接口
public interface UserService {//全查询List<User> findAllUsers();//1027-【从数据库读取用户名信息存入布隆过滤器中】void warnUpUsernames();//1027-【用户登录】User login(String username, String password);}
4. ⭐UserServiceImpl业务实现类
@Service
@Slf4j
public class UserServiceImpl implements UserService {@Autowiredprivate UserDao userDao;@Autowiredprivate StringRedisTemplate stringRedisTemplate;//全查询@Overridepublic List<User> findAllUsers() {return userDao.findAll();}//1027-【从数据库读取用户名信息存入布隆过滤器中】@Overridepublic void warnUpUsernames() {userDao.findAll().forEach(u -> {stringRedisTemplate.opsForValue().getOperations().execute(new DefaultRedisScript<Long>("return redis.call('bf.add',KEYS[1],ARGV[1])", Long.class),new ArrayList<String>() {{add("whiteUsernames");}}, u.getUsername());});}//1027-【用户登录】@Overridepublic User login(String username, String password) {if(!StringUtils.hasText(username)){throw new UsernameIsEmptyException("用户名为空异常");}username = username.trim();if(checkFromWhite(username)){throw new UsernameNotFoundException("用户名不存在异常");}User user = userDao.findByUsernameAndPassword(username, password);if(Objects.isNull(user)){throw new BadCredentialsException("用户名|密码错误");}return user;}//判断用户名是否存在于布隆过滤器private boolean checkFromWhite(String username) {Long isExist = stringRedisTemplate.opsForValue().getOperations().execute(new DefaultRedisScript<Long>("return redis.call('bf.exists',KEYS[1],ARGV[1])", Long.class),new ArrayList<String>() {{add("whiteUsernames");}}, username);return isExist.intValue() == 0;}
5. ⭐UserController控制层接口
@Api(tags = "用户模块接口")
@RestController
@RequestMapping("/api/user")
@Slf4j
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate StringRedisTemplate stringRedisTemplate;//1027-【全查询】@ApiOperation(value = "findAllUsers",notes = "查询所有用户,需要当前用户登录状态")@GetMapping("/findAllUsers")@BmsRole(value="1")public HttpResp<List<User>> findAllUsers(){return HttpResp.success(userService.findAllUsers());}//1027-【用户登录】@ApiOperation(value = "login",notes = "用户登录")@GetMapping("login")public HttpResp login(HttpServletResponse response, String username, String password){//首先调用AuthorityService的login方法进行用户登录验证,返回一个User对象。User user = userService.login(username,password);//然后生成一个JWT作为用户的身份认证凭证,其中包含了用户名和过期时间等信息。//使用JWT.create()创建JWT对象,并使用withClaim()方法设置用户名,withExpiresAt()方法设置过期时间。String salt = Base64.getEncoder().encodeToString((username+":"+password).getBytes(StandardCharsets.UTF_8));log.debug("user:{}",user);String token = JWT.create().withClaim("username", username).withClaim("roleId",""+user.getRoleId()).withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 30)) //30分钟令牌过期.sign(Algorithm.HMAC256(salt)); //使用Algorithm.HMAC256(salt)指定加密算法和密钥,对JWT进行签名。log.debug("用户验证通过,生成token为:{}",token);//将生成的JWT存储到Redis缓存中,使用stringRedisTemplate.opsForValue().set()方法设置键值对,并使用stringRedisTemplate.expire()方法设置过期时间stringRedisTemplate.opsForValue().set(token,salt);stringRedisTemplate.expire(token,60, TimeUnit.MINUTES); //60分钟redis缓存token过期response.addCookie(new Cookie("token",token)); //将JWT作为Cookie添加到HTTP响应中,使用response.addCookie()方法return HttpResp.success(user); //最后返回一个成功的响应,消息体中包含了登录成功的用户对象}}
用户认证解决方案
1. 配置部署拦截器
@Configuration
@Slf4j
public class BmsMvcConfig implements WebMvcConfigurer {@Beanpublic AuthorityInterceptor authorityInterceptor(){log.debug("BmsMvc拦截器启动成功:{}..........",new Date());return new AuthorityInterceptor();}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(authorityInterceptor()).addPathPatterns("/api/**").excludePathPatterns("/api/user/login");}
}
2. ⭐自定义拦截器
@Slf4j
public class AuthorityInterceptor implements HandlerInterceptor {@Autowiredprivate StringRedisTemplate stringRedisTemplate;/**** @param request* @param response* @param handler 当前拦截器拦截的方法* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.debug("已进入拦截器:{}",new Date());String token = request.getHeader("token");//1.从redis中读取token,如果不存在,则用户是非法用户,抛出自定义异常类InvalidTokenExceptionBoolean isRedis = stringRedisTemplate.hasKey(token);if(!isRedis) throw new InvalidTokenException("无效的token");String salt = stringRedisTemplate.opsForValue().get(token);log.debug("salt:{}",salt);DecodedJWT decodedJWT = JWT.require(Algorithm.HMAC256(salt)).build().verify(token);//2.token验证完成正确String roleId = decodedJWT.getClaim("roleId").asString();log.debug("------->roleId:{}",roleId);HandlerMethod method = (HandlerMethod) handler;//System.out.println("----->"+method.getMethod().getDeclaredAnnotation(GetMapping.class));BmsRole bmsRole= method.getMethod().getDeclaredAnnotation(BmsRole.class);String requiredRolId = bmsRole.value();if(!roleId.equals(requiredRolId)){throw new PermissionDeniedException("您没有足够的权限");}//获取请求对象的角色名称//获取请求的地址(uri)
// String requestURI = request.getRequestURI();
// requestURI = requestURI.substring(requestURI.lastIndexOf("/") + 1);
// log.debug("请求路径uri:{}",requestURI);//URL/URI
// System.out.println(handler.getClass());return HandlerInterceptor.super.preHandle(request, response, handler);}
}
3. 在spring.factories文件加载部署
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.****.bms.authority.config.BmsMvcConfig,com.****.bms.authority.handler.UserExceptionHandler
未完待续......
相关文章:

【用户登录】模块之登录认证+鉴权业务逻辑
用户登录——⭐认证功能的流程图: ⭐鉴权流程图: 用户登录功能的Java代码实现 1. 实体类-User orm框架:JPA Table(name "user_tab") Entity Data NoArgsConstructor AllArgsConstructor public class User implements Serializ…...

开启CETOS 裸奔了一年的服务器开启firewall防火墙
记录一下关于firewall,博主非运维专家或服务器专家。 背景 客户有一台裸奔运行了一年多的系统有公网但发现没有开防火墙,iptables和firewall均是关闭状态,通过扫描发现很多漏洞。根据客户要求对端口进行重新梳理且关闭不必要或有潜在风险的…...
eslint识别不了别名解决方法
第一步 npm i eslint-import-resolver-alias -D第二步:在 eslintrc.js 配置 module.exports {settings: {import/resolver: {alias: {map: [// 这里参照webpack的别名配置映射[, ./src]],// 引用的时候可以忽略后缀extensions: [.vue, .js, .ts, .tsx, .jsx, .json…...

【windows 脚本】netsh命令
netsh 是 Windows 操作系统中的一个命令行工具,用于配置和管理网络设置。它提供了一系列的命令和参数,可以用于配置网络接口、防火墙、路由表等网络相关的设置。以下是一些常用的 netsh 命令和用法: 配置静态IP,IP地址、子网掩码和…...

二叉树三种遍历的递归与非递归写法
目录 编辑 一,前序遍历 题目接口: 递归解法: 非递归解法: 二,中序遍历 题目接口: 递归解法: 非递归写法: 三,后序遍历 题目接口: 递归解法&…...

虹科 | 解决方案 | 汽车示波器 远程诊断方案
车厂总部专家实时指导你修车 当一线汽修技师遇到疑难问题无从下手时,可以准备好pico汽车示波器套装,并戴上我们的M400智能AR眼镜,通过语音操作,呼叫主机厂的技术支持老师;老师通过AR眼镜上的摄像头老师可以实时看到现…...

Unity ScrollView最底展示
Unity ScrollView最底展示 问题方案逻辑 问题 比如在做聊天界面的时候我们肯定会使用到ScrollView来进行展示我们的聊天内容,那么这个时候来新消息的时候就需要最底展示,我认为这里有两种方案; 一种是通过算法每一条预制体的高度*一共多少…...

linux常用基本命令大全的使用(三)
🎬作者简介:大家好,我是青衿🥇 ☁️博客首页:CSDN主页石马农青衿 🌄每日一句:努力一点,优秀一点 📑前言 本文主要是linux常用基本命令面试篇文章,如果有什么…...
Qt 实现软件启动界面动画
实现软件启动界面,用到QSplashScreen类。 效果 启动界面 描述 QSplashScreen小部件提供了一个可以在应用程序启动期间显示的启动画面。 启动画面通常是在应用程序启动时显示的小部件。启动画面通常用于启动时间较长的应用程序(例如需要花费一些时间来建…...

2000-2021年三批“智慧城市”试点名单匹配数据
2000-2021年三批“智慧城市”试点名单匹配数据 1、时间:2000-2021年 2、指标:行政区划代码、地区、所属省份、年份、智慧城市试点、最早试点年份 3、来源:住建部公布的三批“国家智慧城市名单” 4、说明:内含原始文件和匹配结…...

H5游戏分享-烟花效果
<!DOCTYPE html> <html dir"ltr" lang"zh-CN"> <head> <meta charset"UTF-8" /> <meta name"viewport" content"widthdevice-width" /> <title>点击夜空欣赏烟花</title> <sc…...

底层驱动day8作业
代码: //驱动程序 #include<linux/init.h> #include<linux/module.h> #include<linux/of.h> #include<linux/of_gpio.h> #include<linux/gpio.h> #include<linux/timer.h>struct device_node *dnode; //unsigned int gpiono; …...

openWRT SFTP 实现远程文件安全传输
🔥博客主页: 小羊失眠啦. 🔖系列专栏: C语言、Linux、 Cpolar ❤️感谢大家点赞👍收藏⭐评论✍️ 文章目录 前言 1. openssh-sftp-server 安装2. 安装cpolar工具3.配置SFTP远程访问4.固定远程连接地址 前言 本次教程我…...

麒麟KYLINOS2303版本上使用KDE桌面共享软件
原文链接:麒麟KYLINOS2303版本上使用KDE桌面共享软件 hello,大家好啊,今天给大家推荐一个在麒麟KYLINOS桌面操作系统2303版本上使用KDE桌面共享软件的文章,通过安装KDE桌面共享软件,可以让远程vnc客户端连接访问本机桌…...

H5游戏源码分享-手机捉鬼游戏
H5游戏源码分享-手机捉鬼游戏 一款考验手速的游戏 <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/html; charsetUTF-8"><title>手机捉鬼 微信HTML5在线朋友圈游戏</title><meta name&…...

vite中将css,js文件归类至文件夹
build: {chunkSizeWarningLimit: 1500,rollupOptions: {output: {// 最小化拆分包manualChunks(id) {if (id.includes(node_modules)) {return id.toString().split(node_modules/)[1].split(/)[0].toString()}},// 用于从入口点创建的块的打包输出格式[name]表示文件名,[hash]…...
【通信原理】第一章|绪论|信息度量和通信系统的性能指标
前言 那么这里博主先安利一些干货满满的专栏了! 首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助。 高质量博客汇总 绪论 1. 信息和信息的度量 定义信息…...
基于STM32+OneNet设计的物联网智能鱼缸(2023升级版)
基于STM32+OneNet设计的智能鱼缸(升级版) 一、前言 随着物联网技术的快速发展,智能家居和智能养殖领域的应用越来越广泛。智能鱼缸作为智能家居和智能养殖的结合体,受到了越来越多消费者的关注。本项目设计一款基于STM32的物联网智能鱼缸,通过集成多种传感器和智能化控制模…...

NET-MongoDB的安装使用
一.下载 MongoDB 点击 Select package 选择自己所需版本后点击下载,本文选用Windows 6.0版本以上 二、配置MongoDB 在 Windows 上,MongoDB 将默认安装在 C:\Program Files\MongoDB 中。 将 C:\Program Files\MongoDB\Server\version_numbe…...

简化geojson策略
1、删除无用的属性,也就是字段,在shp的时候就给删了 用arcgis等等软件都可以做到 2、简化坐标的小数位数 (1)网上推荐的办法,俺不会Python… github.com/perrygeo/geojson-precision (2)曲线…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...

macOS 终端智能代理检测
🧠 终端智能代理检测:自动判断是否需要设置代理访问 GitHub 在开发中,使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新,例如: fatal: unable to access https://github.com/ohmyzsh/oh…...

Linux基础开发工具——vim工具
文章目录 vim工具什么是vimvim的多模式和使用vim的基础模式vim的三种基础模式三种模式的初步了解 常用模式的详细讲解插入模式命令模式模式转化光标的移动文本的编辑 底行模式替换模式视图模式总结 使用vim的小技巧vim的配置(了解) vim工具 本文章仍然是继续讲解Linux系统下的…...