目录

   

一、token用来做什么?

二、代码结构

三、思路

四、实现

4.1、准备SQL语句

4.2、创建SpringBoot项目,添加相关依赖

4.3、application.yml

4.4、实体类

4.5、JWTUtils工具类

4.6、service & serviceImpl

4.7、Mapper

4.8、Handler

4.9、UserMapper.xml

4.10、配置拦截器

4.11、注册拦截器

   

一、token用来做什么?

登录时,验证账号和密码成功后,生成jwt,返回给前端; 前端接收后保存,再做其他操作,比如增删改查时,同时将jwt传给后端进行验证,如果jwt当做参数一起传给后端,那么每个操作都会有jwt,为了方便把jwt放到请求头中,通过拦截器来验证。

二、代码结构

 

三、思路

有请求过来,通过拦截器进行拦截,但放行登录请求,如果登录成功,生成JWT令牌,返回给前端,当前端再有其他请求过来时,拦截器会拦截并解析token,如果通过就允许业务操作,否则就返回相应提示信息。

四、实现

4.1、准备SQL语句

CREATE TABLE user (

id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,

username varchar(255) DEFAULT NULL,

password varchar(255) DEFAULT NULL

)

INSERT INTO `user` VALUES (1, 'chenxin', '123');

INSERT INTO `user` VALUES (2, 'jiandouluo', '123');

4.2、创建SpringBoot项目,添加相关依赖

   

       org.springframework.boot

       spring-boot-starter-web

   

   

       com.auth0

       java-jwt

       3.19.2

   

   

       com.alibaba

       druid-spring-boot-starter

       1.1.17

   

   

       org.mybatis.spring.boot

       mybatis-spring-boot-starter

       2.2.2

   

   

       mysql

       mysql-connector-java

   

   

       org.projectlombok

       lombok

       true

   

   

       org.springframework.boot

       spring-boot-starter-test

       test

   

4.3、application.yml

spring:

datasource:

  url: jdbc:mysql://localhost:3306/jwt?useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai

  username: root

  password: root

  driver-class-name: com.mysql.cj.jdbc.Driver

mybatis:

type-aliases-package: com.chenxin.springboot.jwt.bean

mapper-locations: classpath:mapper/*.xml

logging:

level:

  sql: debug

4.4、实体类

@Data

public class User {

   private String id;

   private String username;

   private String password;

}

4.5、JWTUtils工具类

import com.auth0.jwt.JWT;

import com.auth0.jwt.JWTCreator;

import com.auth0.jwt.algorithms.Algorithm;

import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Calendar;

import java.util.Map;

public class JWTUtils {

   //密钥

   private static final String SING = "chenxin";

   /**

    * 生成token

    */

   public static String getToken(Map map){

       Calendar instance = Calendar.getInstance();

       //默认7天过期

       instance.add(Calendar.DATE,7);

       //创建jwt builder

       JWTCreator.Builder builder = JWT.create();

       map.forEach((k,v)->{

           builder.withClaim(k,v);

      });

       String token = builder.withExpiresAt(instance.getTime())//有效期

              .sign(Algorithm.HMAC256(SING));//密钥

       return token;

  }

   /**

    * 验证token合法性

    */

   public static DecodedJWT verify(String token){

       //返回验证结果(结果是内置的)

       return JWT.require(Algorithm.HMAC256(SING)).build().verify(token);

  }

}

4.6、service & serviceImpl

public interface UserService {

   User login (User user);

}

@Slf4j

@Service

public class UserServiceImpl implements UserService {

   @Autowired

   private UserMapper userMapper;

   @Override

   public User login(User user) {

       User u = userMapper.login(user);

       if(null != u) {

           log.info("登录成功...");

           return u;

      }

       log.info("登录失败...");

       return null;

  }

}

4.7、Mapper

@Mapper

public interface UserMapper {

   User login(User user);

}

4.8、Handler

@RestController

@Slf4j

public class UserHandler {

   @Autowired

   private UserService userService;

   @GetMapping("/user/login")

   public Map login(User user){

       log.info("用户名:[{}]",user.getUsername());

       log.info("密码:[{}]",user.getPassword());

       Map map = new HashMap<>();

       try {

           User userDB = userService.login(user);

           Map payload = new HashMap<>();

           //用户登录成功后的信息放入payload

           payload.put("id",userDB.getId());

           payload.put("username",userDB.getUsername());

           //生成JWT令牌

           String token = JWTUtils.getToken(payload);

           map.put("state",true);

           map.put("token",token);

           map.put("msg","认证成功");

      }catch (Exception e){

           map.put("state",false);

           map.put("msg",e.getMessage());

      }

       return map;

  }

   @PostMapping("/user/test")

   public Map test(String token){

       Map map = new HashMap<>();

       log.info("需要验证token的函数执行了...");

       map.put("state",true);

       map.put("msg","请求成功");

       return map;

  }

}

4.9、UserMapper.xml

       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

   

4.10、配置拦截器

配置拦截器,这样得到jwt后,再次请求时把jwt放到请求头中,就可以不用当参数传递。

import com.auth0.jwt.exceptions.AlgorithmMismatchException;

import com.auth0.jwt.exceptions.SignatureVerificationException;

import com.auth0.jwt.exceptions.TokenExpiredException;

import com.auth0.jwt.interfaces.DecodedJWT;

import com.chenxin.springboot.jwt.util.JWTUtils;

import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.extern.slf4j.Slf4j;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.util.HashMap;

import java.util.Map;

@Slf4j

public class JWTInterceptor implements HandlerInterceptor {

   @Override

   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

       Map map = new HashMap<>();

       // 获取请求头中的令牌

       String token = request.getHeader("token");

       log.info("请求头中的token是:{}",token);

       try {

           if(token==null){

               throw new Exception();

          }

           //验证令牌

           DecodedJWT verify = JWTUtils.verify(token);

           return true;

      } catch (SignatureVerificationException e){

           //e.printStackTrace();

           map.put("msg","无效签名");

      } catch (TokenExpiredException e){

           //e.printStackTrace();

           map.put("msg","token过期");

      } catch (AlgorithmMismatchException e){

           //e.printStackTrace();

           map.put("msg","token算法不一致");

      } catch (Exception e){

           //e.printStackTrace();

           map.put("msg","token无效");

      }

       map.put("state","flase");

       //将map转为json

       String json = new ObjectMapper().writeValueAsString(map);

       response.setContentType("application/json;charset=UTF-8");

       response.getWriter().println(json);

       return false;

  }

   @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 {

  }

}

4.11、注册拦截器

import com.chenxin.springboot.jwt.interceptor.JWTInterceptor;

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 InterceptorConfig implements WebMvcConfigurer {

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(new JWTInterceptor())

//拦截

.addPathPatterns("/user/test")

//放行

.excludePathPatterns("/user/login");

}

}

文章链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。