【wiki知识库】08.添加用户登录功能--后端SpringBoot部分
目录一、今日目标?二、SpringBoot后端实现2.1 新增UserLoginParam2.2 修改UserController2.3 UserServiceImpl代码2.4 创建用户上下文工具类2.5?通过token校验用户重要2.6 创建WebMvcConfig2.7 用户权限校验拦截器* *一、今日目标------ 上篇文章链接【wiki知识库】08.添加用户登录功能–前端Vue部分修改-CSDN博客 这篇文章主要是实现一下用户登录功能的后端部分登录功能需要使用redis不懂redis可以看我之前的一篇文章。 Redis文章链接【Spring】SpringBoot整合Redis用Redis实现限流附Redis解压包_springboot 限流 redis-CSDN博客 那么为什么要用到Redis呢 这个问题关系到整个系统的用户校验当我们登录成功的时候后端会生成一个用于用户校验的token值然后把这个值传给前端每次用户请求后端的时候都要带上这个token值这个token的值当中记录了当前登录的用户是谁还有过期时间等信息这样子就可以防止那些没有登陆的用户去直接访问我们的后端调用接口。所以这个token还是需要妥善保管的一旦token丢失别人就可能用你的token去发送请求修改你的数据。二、SpringBoot后端实现---------------- ### 2.1 新增UserLoginParam 这里也做了校验其实这个事情完全可以放到前端实现但是也要考虑到有直接调用接口的情况这时也要给出错误提示。 Data public class UserLoginParam { NotEmpty(message “【用户名】不能为空”) private String loginName; NotEmpty(message “【密码】不能为空”) Pattern(regexp “^(?![0-9]) ( ? ! [ a − z A − Z ] )(?![a-zA-Z])(?![a−zA−Z])[0-9A-Za-z]{6,32}$”, message “【密码】规则不正确”) private String password; } * * * ### 2.2 修改UserController 直接上代码吧。这里拿到了用户的账号和用户的密码然后判断加密后的密码和数据库中取出来的用户密码是否相同如果相同那么就可以登陆。登陆后通过工具类生成一个不会重复的Long类型的值作为该用户的token然后以token为key登录用户创建的对象作为值保存到redis当中以便于后续用户访问接口时通过用户token来判断是哪个用户访问接口。 PostMapping(“/login”) public CommonResp login(Valid RequestBody UserLoginParam req) { req.setPassword(DigestUtils.md5DigestAsHex(req.getPassword().getBytes())); System.out.println(req); UserLoginVo userLoginResp userService.login(req); Long token snowFlake.nextId(); userLoginResp.setToken(token.toString()); redisTemplate.opsForValue().set(token.toString(), JSONObject.toJSONString(userLoginResp), 3600 * 24, TimeUnit.SECONDS); return new CommonResp(true,“登录成功”,userLoginResp); } GetMapping(“/logout/{token}”) public CommonResp logout(PathVariable String token) { boolean res redisTemplate.delete(token); String message Boolean.TRUE.equals(res) ? “登出成功”:“登出失败”; return new CommonResp(true,message,null); } * * * ### 2.3 UserServiceImpl代码 这个代码没有什么好说的就是查找一次数据库进行账号密码的匹配。 public UserLoginVo login(UserLoginParam req) { User userDb selectByLoginName(req.getLoginName()); if (ObjectUtils.isEmpty(userDb)) { // 用户名不存在 throw new RuntimeException(“用户名不存在”); } else { if (userDb.getPassword().equals(req.getPassword())) { // 登录成功 UserLoginVo userLoginResp CopyUtil.copy(userDb, UserLoginVo.class); return userLoginResp; } else { // 密码不对 throw new RuntimeException(“密码错误”); } } } * * * ### 2.4 创建用户上下文工具类 这个工具类用户用户登录后保存当前用户的上下文。 public class LoginUserContext implements Serializable { private static ThreadLocal user new ThreadLocal(); public static UserLoginVo getUser() { return user.get(); } public static void setUser(UserLoginVo user) { LoginUserContext.user.set(user); } } * * * ### 2.5通过token校验用户重要 校验用户token需要使用到拦截器或者过滤器这里我使用拦截器进行用户token的校验。整体的校验流程如下 以下就是登录拦截器的代码 / * 拦截器Spring框架特有的常用于登录校验权限校验请求日志打印 */ Component public class LoginInterceptor implements HandlerInterceptor { private static final Logger LOG LoggerFactory.getLogger(LoginInterceptor.class); Resource private RedisTemplate redisTemplate; Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // OPTIONS请求不做校验, // 前后端分离的架构, 前端会发一个OPTIONS请求先做预检, 对预检请求不做校验 if (request.getMethod().toUpperCase().equals(“OPTIONS”)) { return true; } String path request.getRequestURL().toString(); LOG.info(“接口登录拦截path{}”, path); //获取header的token参数 String token request.getHeader(“token”); LOG.info(“登录校验开始token{}”, token); if (token null || token.isEmpty()) { LOG.info(“token为空请求被拦截”); response.setStatus(HttpStatus.UNAUTHORIZED.value()); return false; } Object object redisTemplate.opsForValue().get(token); // 证明redis中的用户信息过期了需要重新登陆 if (object null) { LOG.warn(“token无效请求被拦截”); response.setStatus(HttpStatus.UNAUTHORIZED.value()); return false; } else { LOG.info(“已登录{}”, object); LoginUserContext.setUser(JSON.parseObject((String) object, UserLoginVo.class)); return true; } } Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { } Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { } } 接下来要把这个拦截器注册到配置当中。 * * * ### 2.6 创建WebMvcConfig 在config包下创建该类。这个类当中配置了两个拦截器一个是登录拦截器另一个是用户权限校验拦截器。用户校验拦截器下边再说。登录拦截器只需要部分接口进行拦截就可以了毕竟有的接口不需要登陆用户就可以访问。 有一点值得注意的是在这个配置类中配置的拦截器的顺序会影响校验结果校验的流程是根据你配置的拦截器的顺序从上往下校验的如果你把拦截器配置写反了就会出错。 addInterceptor 注册一个拦截器 addPathPatterns 该拦截器需要拦截的路径 excludePathPatterns 该拦截器不需要拦截的路径 Configuration public class SpringMvcConfig implements WebMvcConfigurer { Resource LoginInterceptor loginInterceptor; Resource ActionInterceptor actionInterceptor; public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) .addPathPatterns(/) .excludePathPatterns( “/test/, /redis/”, “/user/login”, “/user/logout/, “/category/all”, “/ebook/list”, /doc/all/”, “/doc/find-content/**”, ); registry.addInterceptor(actionInterceptor) .addPathPatterns( //save, “//delete/**, //reset-password”); } } * * * ### 2.7 用户权限校验拦截器 看到下方的代码你应该知道了用户上下文的作用通过用户上下文拿到用户的信息来判断该用户是否有访问该接口的权利我们拒绝非admin用户外的用户进行增删改操作。 但是这种方法有点不太好不知道你们有没有感觉到一旦用户多了之后如果你想给用户分配权限你就要添加很多的用户在这里。所以一种更好的方式就是RBAC权限校验大家可以自己了解一下也有更好的权限校验框架SpringSecurity但是作为一个比较简单的项目引入这个框架的学习成本就太大了。 /** * 拦截器Spring框架特有的常用于登录校验权限校验请求日志打印 */ Component public class ActionInterceptor implements HandlerInterceptor { private static final Logger LOG LoggerFactory.getLogger(ActionInterceptor.class); Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { // OPTIONS请求不做校验, // 前后端分离的架构, 前端会发一个OPTIONS请求先做预检, 对预检请求不做校验 if (“OPTIONS”.equals(request.getMethod().toUpperCase())) { return true; } UserLoginVo userLoginResp LoginUserContext.getUser(); if (“admin”.equals(userLoginResp.getLoginName())) { // admin用户不拦截 return true; } LOG.info(“操作被拦截”); response.setStatus(HttpStatus.OK.value()); CommonResp commonResp new CommonResp(false,“普通用户暂不开放增删改操作”,null); response.setContentType(“application/json;charsetUTF-8”); response.setCharacterEncoding(“UTF-8”); response.getWriter().print(JSONObject.toJSON(commonResp)); return false; } }

相关新闻

AI算力成本失控?从估算到优化的完整工程指南

AI算力成本失控?从估算到优化的完整工程指南

“AI支出暴增2013%,马斯克原来在给黄仁勋‘打工’?”这句话最近在技术圈里传播很广。多数人把它当商业八卦看,但我更建议把它读成一道算力成本题。这个数字背后真正要回答的问题是:AI公司的钱到底烧在了哪里,为什么算力…

2026/11/7 8:58:51 阅读更多 →
考研与求职双线作战:一个普通本科生的时间管理与决策复盘

考研与求职双线作战:一个普通本科生的时间管理与决策复盘

1. 一个普通人的十字路口:考研与求职的双重奏2021年,对于很多即将毕业的大学生来说,是一个充满不确定性的年份。我,阿孟,就是这茫茫人海中的一个。站在人生的十字路口,左边是通往学术深造的考研独木桥&…

2026/11/7 8:58:51 阅读更多 →
蓝桥杯Scratch国赛真题解析:计算思维与模块化编程实战指南

蓝桥杯Scratch国赛真题解析:计算思维与模块化编程实战指南

1. 项目概述:为什么我们要死磕蓝桥杯Scratch国赛真题?如果你正在辅导孩子学习Scratch,或者自己就是一名青少年编程的教练,那么“蓝桥杯”这三个字对你来说一定不陌生。它几乎是国内青少年编程领域最具分量的赛事之一,尤…

2026/10/25 23:13:00 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/6 15:21:35 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/6 9:29:27 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/6 22:01:11 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/6 22:01:11 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/6 8:08:42 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/6 22:01:09 阅读更多 →

日新闻

周新闻

月新闻