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

【SpringBoot】实战-开发接口-用户-登录

 登录

界面

接口文档

逻辑

代码

     @PostMapping("/login")public Result<String> login(@Pattern(regexp = "^\\S{5,16}$")String username,@Pattern(regexp = "^\\S{5,16}$")String password){//根据用户查询userUser user = userService.findByUsername(username);//判断是否查到if (user != null){//判断密码是否正确if (Md5Util.checkPassword(password,user.getPassword())){return Result.success();}else {return Result.error("登录失败:密码错误");}}else {return Result.error("登录失败:用户不存在");}}

登录认证 

在没有登录的情况不能访问Article的内容,所以需要验证登录的状态

没有登录就可以访问,在访问list接口前,就需要对登录的状态进行验证

借助令牌可以解决以上访问的问题

令牌就是一段字符串

令牌要求

  • 承载业务数据,减少后续请求查询数据库的次数
  • 放篡改,保证信息的合法性和有效性

JWT令牌

简介

全称:json web token(https://jwt.io/)

定义了一种简洁的、自包含的格式,用于通信双方以json数据格式安全的传输信息

组成:

  • 第一部分:header(头),记录令牌类型,签名算法等。列如{“alg”:“HS256”,“type”:“JWT”} alg:算法 
  • 第二部分:Payload(有效载荷、不要存放私密数据),携带一些自定义信息。默认信息等。例如{“id”:“1”,“username”:“tom”} 使用Base64(编码方式/公开)转换
  • 第三部分:Signature(签名),防止Token被篡改,确保安全性。将header,payload,加入指定秘钥(通过头部算法alg来指定),通过指定签名算法计算而来

令牌的生成

添加依赖

<!--    JWT令牌--><dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.4.0</version></dependency><!--    单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency>

测试代码 

package com.zwh;import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import org.junit.jupiter.api.Test;import java.util.Date;
import java.util.HashMap;
import java.util.Map;public class JwtTest {@Testpublic  void  testGen(){Map<String,Object> claims = new HashMap<>();claims.put("id","1");claims.put("username","张三");String token = JWT.create().withClaim("user",claims)//添加载荷.withExpiresAt(new Date(System.currentTimeMillis()+1000*60*60*12))//添加过期时间.sign(Algorithm.HMAC256("zwh"));//签名(指定算法,配置秘钥)System.out.println(token);}
}

运行

令牌的验证

@Testvoid parseToken(){String token ="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoiMSIsInVzZXJuYW1lIjoi5byg5LiJIn0sImV4cCI6MTc1MjcxMzU5N30.VcdVoQOieNVvE1C8wSb2COqiVTNtIW80ahFJ6ZCzURU";JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("zwh")).build();DecodedJWT decodedJWT = jwtVerifier.verify(token);Map<String, Claim> claims = decodedJWT.getClaims();System.out.println(claims.get("user"));}

注意事项

  •  JWT验证时使用的签名秘钥,必须和生成JWT令牌时使用的秘钥是配套的
  • 如果JWT令牌解析校验时报错,则说明JWT令牌被篡改或失效了,令牌非法

 设置令牌

修改登陆代码

@PostMapping("/login")public Result<String> login(@Pattern(regexp = "^\\S{5,16}$")String username,@Pattern(regexp = "^\\S{5,16}$")String password){//根据用户查询userUser user = userService.findByUsername(username);//判断是否查到if (user != null){//判断密码是否正确if (Md5Util.checkPassword(password,user.getPassword())){Map<String, Object> map = new HashMap<>();map.put("username",user.getUsername());map.put("id",user.getId());String token = JwtUtil.genToken(map);return Result.success(token);}else {return Result.error("登录失败:密码错误");}}else {return Result.error("登录失败:用户不存在");}}

测试

验证令牌

@RestController
@RequestMapping("/article")
public class ArticleController {@GetMapping("/list")public Result<String> list(@RequestHeader(name = "Authorization") String token, HttpServletResponse response){//验证tokentry {Map<String,Object> claims=JwtUtil.parseToken(token);return Result.success("所有的文章数据。。。。");} catch (Exception e) {//http响应码为401response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);return Result.error("未登录");}}
}

拦截器

多处用到令牌验证

拦截器 :多个接口有同样的操作需要完成

package com.zwh.interceptors;import com.zwh.utils.JwtUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;import java.util.Map;@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//令牌验证String token = request.getHeader("Authorization");try {Map<String,Object> claims = JwtUtil.parseToken(token);return true;//放行} catch (Exception e) {response.setStatus(401);return  false;//不放行}}
}

package com.zwh.config;import com.zwh.interceptors.LoginInterceptor;
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 LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//登录和注册接口不拦截registry.addInterceptor(loginInterceptor).excludePathPatterns("/user/login","/user/register");}
}

 

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

相关文章:

  • APIs案例及知识点串讲(中)
  • docker--安装--原理
  • 寻找数组中的多数元素:HashMap方法解析
  • 【无标题】构建黑洞虚维度空间的完整理论
  • COZE官方文档基础知识解读第五期 —— 插件
  • Android默认背光亮度配置说明
  • 如何清除 npm 缓存
  • web前端渡一大师课 CSS属性计算过程
  • 【Android】ViewBinding(视图绑定)
  • 华为P30/pro (ELE-AL00) 鸿蒙4.2降级 EMUI 9
  • 单片机+微信小程序做示波器
  • 深入解析:前端 localStorage 的读取是异步的吗?为什么硬盘 I/O 是异步的,而它却是同步的?
  • Linux 软件安装的四种方式详解
  • HTTP 状态码笔记
  • 网络原理 —— HTTP
  • uniapp用webview导入本地网页,ios端打开页面空白问题
  • 自定义 django 中间件
  • 《小白学习产品经理》第六章:方法论之SWOT分析
  • 3D工业相机是什么?如何选择和使用它?
  • docker安装与简单项目上手
  • 5. 实战项目类:《用TypeScript + Vite从零搭建企业级React应用》
  • Django由于数据库版本原因导致数据库迁移失败解决办法
  • 我的开发日志:随机数小程序
  • redis中间件
  • 手撕Spring底层系列之:后置处理器“PostProcessor”
  • Vmware虚拟机使用仅主机模式共享物理网卡访问互联网
  • 研报复现|格雷厄姆成长股内在价值策略
  • Error: llama runner process has terminated: exit status 2
  • 实习Last Day研二Last Day
  • 纯前端html实现图片坐标与尺寸(XY坐标及宽高)获取