当前位置: 首页 > news >正文

后端学习笔记--登录认证

基础实现

本质就是查询语句

控制器

@Slf4j
@RequestMapping("/login")
@RestController
public class LoginController {@Autowiredprivate EmpService empService;@PostMappingpublic Result login(@RequestBody Emp  emp){log.info("员工登录:{}", emp);LoginInfo loginInfo = empService.login(emp);if(loginInfo == null){return Result.error("用户名或密码错误");}return Result.success(loginInfo);}
}

逻辑层

@Overridepublic LoginInfo login(Emp emp) {//1.调用mapper接口,根据用户名和密码查询员工Emp e = empMapper.selectByUsernameAndPassword(emp);//2.判断员工是否为空if(e!= null){log.info("登录成功,员工信息:{}", e);return new LoginInfo(e.getId(),e.getUsername(),"",e.getName());}//3.不存在返回NULLreturn null;}
/*** 根据用户名和密码查询员工* @param emp* @return*/@Select("select id,username,name from emp where username = #{username} and password = #{password}")Emp selectByUsernameAndPassword(Emp emp);

登录校验

会话技术

方案一 Cookie

//设置Cookie@GetMapping("/c1")public Result cookie1(HttpServletResponse response){response.addCookie(new Cookie("login_username","FeiTwnd")); //设置Cookie/响应Cookiereturn Result.success();}//获取Cookie@GetMapping("/c2")public Result cookie2(HttpServletRequest request){Cookie[] cookies = request.getCookies();for (Cookie cookie : cookies) {if(cookie.getName().equals("login_username")){System.out.println("login_username: "+cookie.getValue()); //输出name为login_username的cookie}}return Result.success();}

   方案二 Session

@GetMapping("/s1")public Result session1(HttpSession session){log.info("HttpSession-s1: {}", session.hashCode());session.setAttribute("loginUser", "tom"); //往session中存储数据return Result.success();}@GetMapping("/s2")public Result session2(HttpSession session){log.info("HttpSession-s2: {}", session.hashCode());Object loginUser = session.getAttribute("loginUser"); //从session中获取数据log.info("loginUser: {}", loginUser);return Result.success(loginUser);}

方案三 令牌(主流方案)

JWT令牌

介绍

令牌的生成和解析

生成令牌

工具类

package cc.feitwnd.utils;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;import java.util.Date;
import java.util.Map;public class JwtUtils {private static String signKey = "RmVpVHduZA==";  // Base64编码的签名密钥private static Long expire = (long) (12 * 60 * 60 * 1000);/*** 生成JWT令牌* @return*/public static String generateJwt(Map<String,Object> claims){String jwt = Jwts.builder().addClaims(claims).signWith(SignatureAlgorithm.HS256, signKey).setExpiration(new Date(System.currentTimeMillis() + expire)).compact();return jwt;}/*** 解析JWT令牌* @param jwt JWT令牌* @return JWT第二部分负载 payload 中存储的内容*/public static Claims parseJWT(String jwt){Claims claims = Jwts.parser().setSigningKey(signKey).parseClaimsJws(jwt).getBody();return claims;}
}

逻辑层

@Overridepublic LoginInfo login(Emp emp) {//1.调用mapper接口,根据用户名和密码查询员工Emp e = empMapper.selectByUsernameAndPassword(emp);//2.判断员工是否为空if(e!= null){log.info("登录成功,员工信息:{}", e);Map<String,Object> claims = new HashMap<>();claims.put("id",e.getId());claims.put("username",e.getUsername());String jwt = JwtUtils.generateJwt(claims);return new LoginInfo(e.getId(),e.getUsername(),jwt,e.getName());}//3.不存在返回NULLreturn null;}

过滤器Filter

介绍

package cc.feitwnd.filter;import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import lombok.extern.slf4j.Slf4j;import java.io.IOException;@Slf4j
@WebFilter(urlPatterns = "/*")
public class DemoFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {log.info("DemoFilter init...初始化方法运行");}//拦截到请求之后执行,会执行多次@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {log.info("DemoFilter doFilter...执行方法运行");}@Overridepublic void destroy() {log.info("DemoFilter destroy...销毁方法运行");}
}

令牌校验Filter

令牌校验Filter-流程

package cc.feitwnd.filter;import cc.feitwnd.utils.JwtUtils;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;import java.io.IOException;@Slf4j
@WebFilter(urlPatterns = "/*")
public class TokenFilter  implements Filter {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;//1.获取请求路径String requestURI = request.getRequestURI();//2.判断是否为登录请求,是则放行if(requestURI.contains("login")){log.info("登录请求,放行");filterChain.doFilter(request,response);return;}//3.获取tokenString token = request.getHeader("token");log.info("token:{}",token);//4.判断token是否存在,不存在返回401状态码if(token == null || token.isEmpty()){log.info("token不存在,返回401状态码");response.setStatus(401);return;}//5.如果token存在,校验tokentry{JwtUtils.parseJWT(token);}catch (Exception e){log.info("token无效,返回401状态码");response.setStatus(401);return;}//6.放行log.info("token有效,放行");filterChain.doFilter(request,response);}
}

Filter-详解

拦截路径

过滤器链

按照文件名来决定执行顺序

拦截器Interceptor

入门程序

1.定义拦截器

package cc.feitwnd.interceptor;import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;@Slf4j
@Component
public class DemoInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info("preHandle");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("postHandle");}//视图渲染之后执行@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}

注册拦截器

package cc.feitwnd.config;import cc.feitwnd.interceptor.DemoInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 配置类*/
@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate DemoInterceptor demoInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(demoInterceptor).addPathPatterns("/**");}
}

基于拦截器实现令牌校验功能

 

package cc.feitwnd.interceptor;import cc.feitwnd.utils.JwtUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;@Slf4j
@Component
public class TokenInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.获取请求路径String requestURI = request.getRequestURI();//2.判断是否为登录请求,是则放行if(requestURI.contains("login")){log.info("登录请求,放行");return true;}//3.获取tokenString token = request.getHeader("token");log.info("token:{}",token);//4.判断token是否存在,不存在返回401状态码if(token == null || token.isEmpty()){log.info("token不存在,返回401状态码");response.setStatus(401);return false;}//5.如果token存在,校验tokentry{JwtUtils.parseJWT(token);}catch (Exception e){log.info("token无效,返回401状态码");response.setStatus(401);return false;}//6.放行log.info("token有效,放行");return true;}
}

拦截路径

执行流程

http://www.dtcms.com/a/528457.html

相关文章:

  • 【开题答辩全过程】以 餐健一体化管理系统为例,包含答辩的问题和答案
  • 大型网站建设的难点是什么企业网站建设图片
  • 智能体通信协议详解:MCP/A2A/ANP
  • 公司大厅设计效果图大全站长工具seo综合查询
  • 【MYSQL】第二篇:SQL进阶指南:增删改查与性能优化实战手册
  • Spring Boot3零基础教程,Profile 配置文件 按环境分配置文件,笔记56
  • 小白python入门 - 7. Python分支与循环结构实战:从基础语法到代码逻辑解析
  • Chrony服务器同步时间服务器实验
  • 万互网站建站网站建设怎么提需求
  • 国产 做 视频网站陕西建筑培训网
  • [人工智能-大模型-69]:模型层技术 - 计算机处理问题的几大分支:数值型性问题、非数值型问题?
  • 0. Qt 安装及源码及报错
  • jQuery 事件方法详解
  • 基于Python大数据的热门游戏推荐系统
  • 网站如何做关健词收录网站应该如何推广
  • 网站应该如何进行优化微信企业网站 源码下载
  • LlamaFactory的docker-compose安装
  • RK3568笔记102:基于LVGL8的车载娱乐小平板设计
  • 技术随笔:Node.js ESM 中巧用 `-r dotenv/config` 解决环境变量异步加载问题
  • 网站做端口是什么有没有可以免费做试卷的网站_最好可以学会...
  • 游戏人物设计 简单思路 那任务简单说是显示的 完成任务是每个条件脚本自己判断 完成后发给任务脚本信息
  • 利用消息队列(MQ)设计:解耦与异步削峰的艺术
  • 自由学习记录(111)
  • ESP32使用笔记(基于ESP-IDF):小智AI的ESP32项目架构与启动流程全面解析
  • 网站建设 软文网站创作思路
  • 未来之窗昭和仙君(三十七)抽奖随机算法修仙体——东方仙盟筑基期
  • HCIP---作业
  • 海天建设集团公司网站vi应用设计
  • Mybatis10-xml文件与mapper文件的目录位置说明
  • 安全的网站网站开发要