当前位置:   article > 正文

Spring Boot 笔记 007 创建接口_登录

Spring Boot 笔记 007 创建接口_登录

1.1 登录接口需求

1.2 JWT令牌

1.2.1 JWT原理

1.2.2 引入JWT坐标

1.2.3 单元测试

1.2.3.1 引入springboot单元测试坐标

1.2.3.2 在单元测试文件夹中创建测试类

1.2.3.3 运行测试类中的生成和解析方法

  1. package com.geji;
  2. import com.auth0.jwt.JWT;
  3. import com.auth0.jwt.JWTVerifier;
  4. import com.auth0.jwt.algorithms.Algorithm;
  5. import com.auth0.jwt.interfaces.Claim;
  6. import com.auth0.jwt.interfaces.DecodedJWT;
  7. import org.junit.jupiter.api.Test;
  8. import java.util.Date;
  9. import java.util.HashMap;
  10. import java.util.Map;
  11. public class JwtTest {
  12. @Test
  13. public void testGen() {
  14. Map<String, Object> claims = new HashMap<>();
  15. claims.put("id", 1);
  16. claims.put("username", "张三");
  17. //生成jwt的代码
  18. String token = JWT.create()
  19. .withClaim("user", claims)//添加载荷
  20. .withExpiresAt(new Date(System.currentTimeMillis() + 1000*60))//添加过期时间
  21. .sign(Algorithm.HMAC256("geji"));//指定算法,配置秘钥
  22. System.out.println(token);
  23. }
  24. @Test
  25. public void testParse() {
  26. //定义字符串,模拟用户传递过来的token
  27. String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoxLCJ1c2VybmFtZSI6IuW8oOS4iSJ9LCJleHAiOjE3MDc4MTA0NTh9.Ir8IDQ673BoD86ubm8nMo_F91P-ytCd2_MaDzi5mONo";
  28. JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("geji")).build();
  29. DecodedJWT decodedJWT = jwtVerifier.verify(token);//验证token,生成一个解析后的JWT对象
  30. Map<String, Claim> claims = decodedJWT.getClaims();
  31. System.out.println(claims.get("user"));
  32. //如果篡改了头部和载荷部分的数据,那么验证失败
  33. //如果秘钥改了,验证失败
  34. //token过期
  35. }
  36. }

1.2.4 在utils包中添加jwt工具类

  1. package com.geji.utils;
  2. import com.auth0.jwt.JWT;
  3. import com.auth0.jwt.algorithms.Algorithm;
  4. import java.util.Date;
  5. import java.util.Map;
  6. public class JwtUtil {
  7. private static final String KEY = "geji";
  8. //接收业务数据,生成token并返回
  9. public static String genToken(Map<String, Object> claims) {
  10. return JWT.create()
  11. .withClaim("claims", claims)
  12. .withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 ))
  13. .sign(Algorithm.HMAC256(KEY));
  14. }
  15. //接收token,验证token,并返回业务数据
  16. public static Map<String, Object> parseToken(String token) {
  17. return JWT.require(Algorithm.HMAC256(KEY))
  18. .build()
  19. .verify(token)
  20. .getClaim("claims")
  21. .asMap();
  22. }
  23. }

1.3 拦截器

1.3.1 编写拦截器

  1. package com.geji.interceptors;
  2. import com.geji.pojo.Result;
  3. import com.geji.utils.JwtUtil;
  4. import jakarta.servlet.http.HttpServletRequest;
  5. import jakarta.servlet.http.HttpServletResponse;
  6. import org.springframework.stereotype.Component;
  7. import org.springframework.web.servlet.HandlerInterceptor;
  8. import java.util.Map;
  9. @Component
  10. public class LoginInterceptor implements HandlerInterceptor {
  11. @Override
  12. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  13. //令牌验证
  14. String token = request.getHeader("Authorization");
  15. //验证token
  16. try{
  17. Map<String,Object> claims= JwtUtil.parseToken(token);
  18. return true;
  19. }catch (Exception e){
  20. response.setStatus(401);
  21. return false;
  22. }
  23. }
  24. }

1.3.2 注册拦截器,登录和注册接口需要放行

  1. package com.geji.config;
  2. import com.geji.interceptors.LoginInterceptor;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
  6. import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
  7. @Configuration
  8. public class WebConfig implements WebMvcConfigurer {
  9. @Autowired
  10. private LoginInterceptor loginInterceptor;
  11. @Override
  12. public void addInterceptors(InterceptorRegistry registry) {
  13. //登录接口和注册接口不拦截
  14. registry.addInterceptor(loginInterceptor).excludePathPatterns("/user/login","/user/register");
  15. }
  16. }

1.4 编写controller

1.4.1 编写login controller

  1. package com.geji.controller;
  2. import com.geji.pojo.Result;
  3. import com.geji.pojo.User;
  4. import com.geji.service.UserService;
  5. import com.geji.utils.JwtUtil;
  6. import com.geji.utils.Md5Util;
  7. import jakarta.validation.constraints.Pattern;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.validation.annotation.Validated;
  10. import org.springframework.web.bind.annotation.PostMapping;
  11. import org.springframework.web.bind.annotation.RequestMapping;
  12. import org.springframework.web.bind.annotation.RestController;
  13. import java.util.HashMap;
  14. import java.util.Map;
  15. import java.util.concurrent.TimeUnit;
  16. @RestController
  17. @RequestMapping("/user")
  18. @Validated
  19. public class UserController {
  20. @Autowired
  21. private UserService userService;
  22. @PostMapping("/register")
  23. public Result register(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$") String password) {
  24. //查询用户
  25. User u = userService.findByUserName(username);
  26. if (u == null) {
  27. //没有占用
  28. //注册
  29. userService.register(username, password);
  30. return Result.success();
  31. } else {
  32. //占用
  33. return Result.error("用户名已被占用");
  34. }
  35. }
  36. @PostMapping("/login")
  37. public Result<String> login(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$") String password) {
  38. //根据用户名查询用户
  39. User loginUser = userService.findByUserName(username);
  40. //判断该用户是否存在
  41. if (loginUser == null) {
  42. return Result.error("用户名错误");
  43. }
  44. //判断密码是否正确 loginUser对象中的password是密文
  45. if (Md5Util.getMD5String(password).equals(loginUser.getPassword())) {
  46. //登录成功
  47. Map<String, Object> claims = new HashMap<>();
  48. claims.put("id", loginUser.getId());
  49. claims.put("username", loginUser.getUsername());
  50. String token = JwtUtil.genToken(claims);
  51. //把token存储到redis中
  52. // ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
  53. // operations.set(token,token,1, TimeUnit.HOURS);
  54. return Result.success(token);
  55. }
  56. return Result.error("密码错误");
  57. }
  58. }

1.4.2 编写article list controller

  1. package com.geji.controller;
  2. import com.geji.pojo.Result;
  3. import com.geji.utils.JwtUtil;
  4. import jakarta.servlet.http.HttpServletResponse;
  5. import org.springframework.web.bind.annotation.GetMapping;
  6. import org.springframework.web.bind.annotation.RequestHeader;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.RestController;
  9. import java.util.Map;
  10. @RestController
  11. @RequestMapping("/article")
  12. public class ArticleController {
  13. @GetMapping("/list")
  14. public Result<String> list(){
  15. return Result.success("所有文章数据...");
  16. }
  17. }

1.5 测试

1.5.1 获取令牌

1.5.2 带请求头

1.4.3 不带请求头

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/120985
推荐阅读
相关标签
  

闽ICP备14008679号