赞
踩
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 运行测试类中的生成和解析方法
- package com.geji;
-
- import com.auth0.jwt.JWT;
- import com.auth0.jwt.JWTVerifier;
- import com.auth0.jwt.algorithms.Algorithm;
- import com.auth0.jwt.interfaces.Claim;
- import com.auth0.jwt.interfaces.DecodedJWT;
- import org.junit.jupiter.api.Test;
-
- import java.util.Date;
- import java.util.HashMap;
- import java.util.Map;
-
- public class JwtTest {
-
- @Test
- public void testGen() {
- Map<String, Object> claims = new HashMap<>();
- claims.put("id", 1);
- claims.put("username", "张三");
- //生成jwt的代码
- String token = JWT.create()
- .withClaim("user", claims)//添加载荷
- .withExpiresAt(new Date(System.currentTimeMillis() + 1000*60))//添加过期时间
- .sign(Algorithm.HMAC256("geji"));//指定算法,配置秘钥
-
- System.out.println(token);
-
- }
-
- @Test
- public void testParse() {
- //定义字符串,模拟用户传递过来的token
- String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoxLCJ1c2VybmFtZSI6IuW8oOS4iSJ9LCJleHAiOjE3MDc4MTA0NTh9.Ir8IDQ673BoD86ubm8nMo_F91P-ytCd2_MaDzi5mONo";
-
- JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("geji")).build();
-
- DecodedJWT decodedJWT = jwtVerifier.verify(token);//验证token,生成一个解析后的JWT对象
- Map<String, Claim> claims = decodedJWT.getClaims();
- System.out.println(claims.get("user"));
-
- //如果篡改了头部和载荷部分的数据,那么验证失败
- //如果秘钥改了,验证失败
- //token过期
- }
- }
1.2.4 在utils包中添加jwt工具类
- package com.geji.utils;
-
- import com.auth0.jwt.JWT;
- import com.auth0.jwt.algorithms.Algorithm;
-
- import java.util.Date;
- import java.util.Map;
-
- public class JwtUtil {
-
- private static final String KEY = "geji";
-
- //接收业务数据,生成token并返回
- public static String genToken(Map<String, Object> claims) {
- return JWT.create()
- .withClaim("claims", claims)
- .withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 ))
- .sign(Algorithm.HMAC256(KEY));
- }
-
- //接收token,验证token,并返回业务数据
- public static Map<String, Object> parseToken(String token) {
- return JWT.require(Algorithm.HMAC256(KEY))
- .build()
- .verify(token)
- .getClaim("claims")
- .asMap();
- }
-
- }
1.3 拦截器
1.3.1 编写拦截器
- package com.geji.interceptors;
-
- import com.geji.pojo.Result;
- import com.geji.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 {
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- //令牌验证
- String token = request.getHeader("Authorization");
- //验证token
- try{
- Map<String,Object> claims= JwtUtil.parseToken(token);
-
- return true;
- }catch (Exception e){
- response.setStatus(401);
- return false;
- }
- }
-
-
- }
1.3.2 注册拦截器,登录和注册接口需要放行
- package com.geji.config;
-
- import com.geji.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 {
-
- @Autowired
- private LoginInterceptor loginInterceptor;
-
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- //登录接口和注册接口不拦截
- registry.addInterceptor(loginInterceptor).excludePathPatterns("/user/login","/user/register");
- }
- }
1.4 编写controller
1.4.1 编写login controller
- package com.geji.controller;
-
- import com.geji.pojo.Result;
- import com.geji.pojo.User;
- import com.geji.service.UserService;
- import com.geji.utils.JwtUtil;
- import com.geji.utils.Md5Util;
- import jakarta.validation.constraints.Pattern;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.validation.annotation.Validated;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import java.util.HashMap;
- import java.util.Map;
- import java.util.concurrent.TimeUnit;
-
- @RestController
- @RequestMapping("/user")
- @Validated
- public class UserController {
-
- @Autowired
- private UserService userService;
-
- @PostMapping("/register")
- public Result register(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$") String password) {
-
- //查询用户
- User u = userService.findByUserName(username);
- if (u == null) {
- //没有占用
- //注册
- userService.register(username, password);
- return Result.success();
- } else {
- //占用
- return Result.error("用户名已被占用");
- }
- }
-
- @PostMapping("/login")
- public Result<String> login(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$") String password) {
- //根据用户名查询用户
- User loginUser = userService.findByUserName(username);
- //判断该用户是否存在
- if (loginUser == null) {
- return Result.error("用户名错误");
- }
-
- //判断密码是否正确 loginUser对象中的password是密文
- if (Md5Util.getMD5String(password).equals(loginUser.getPassword())) {
- //登录成功
- Map<String, Object> claims = new HashMap<>();
- claims.put("id", loginUser.getId());
- claims.put("username", loginUser.getUsername());
- String token = JwtUtil.genToken(claims);
- //把token存储到redis中
- // ValueOperations<String, String> operations = stringRedisTemplate.opsForValue();
- // operations.set(token,token,1, TimeUnit.HOURS);
- return Result.success(token);
- }
- return Result.error("密码错误");
- }
- }
1.4.2 编写article list controller
- package com.geji.controller;
-
- import com.geji.pojo.Result;
- import com.geji.utils.JwtUtil;
- import jakarta.servlet.http.HttpServletResponse;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RequestHeader;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import java.util.Map;
-
- @RestController
- @RequestMapping("/article")
- public class ArticleController {
- @GetMapping("/list")
- public Result<String> list(){
- return Result.success("所有文章数据...");
-
- }
- }
1.5 测试
1.5.1 获取令牌
1.5.2 带请求头
1.4.3 不带请求头
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。