Spring Boot整合JWT的实现步骤

springboot整合jwt步骤:

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

代码

代码结构图如下,除了常规的controller、entity、mapper和service层,还有两个拦截器和注册拦截器,图中用红字进行注释(这篇文章稍微有点长,因为我把代码都放上来了,结合下边的思路和结构图就能理解个大概)。

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

1、创建jwt数据库,然后创建user表

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

插入数据

INSERT INTO `user` VALUES (1, 'zhangsan', '123');
INSERT INTO `user` VALUES (2, 'lisi', '123');

2、创建Spring Boot项目,在pom文件中,添加jwt等一些依赖和properties:

        <!--jwt-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.4</version>
        </dependency>
        <!--我的mysql是5.6,所以这里是5.1版本-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.3.8</version>
        </dependency>

编写application.properties

server.port=8899
spring.application.name=jwt

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/jwt?useSSL=true&characterEncoding=utf-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root

mybatis.type-aliases-package=com.jwt.entity
mybatis.mapper-locations=classpath:mapper/*Mapper.xml

#打印sql
logging.level.com.jwt.mapper=debug

3、编写代码

3.1、编写entity包下的User

public class User {
    private String id;
    private String username;
    private String password;
    //省略了get和set方法
}

3.2、编写util包下的JWTUtils

public class JWTUtils {

    private static final String SING = "lu123456";

    /**
     * 生成token
     */
    public static String getToken(Map<String,String> 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);
    }
}

3.3、编写controller层下UserController

@RestController
@Slf4j
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/user/login")
    public Map<String,Object> login(User user){
        log.info("用户名:[{}]",user.getUsername());
        log.info("密码:[{}]",user.getPassword());

        Map<String, Object> map = new HashMap<>();

        try {
            User userDB = userService.login(user);
            Map<String,String> payload = new HashMap<>();
            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<String,Object> test(String token){
        Map<String, Object> map = new HashMap<>();
        map.put("state",true);
        map.put("msg","请求成功");
        return map;
    }
}

3.4、编写service层下UserService类和UserServiceImpl

public interface UserService {
    User login (User user);
}

实现类:

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    @Transactional(propagation = Propagation.SUPPORTS)
    public User login(User user) {
        //查询数据库
        User userDB = userMapper.login(user);
        if (userDB != null){
            return userDB;
        }
        throw new RuntimeException("登录失败");
    }
}

3.5、编写mapper层的UserMapper

@Mapper
public interface UserMapper {
    User login(User user);
}

3.6、编写与UserMapper 对应的UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jwt.mapper.UserMapper">

    <select id="login" parameterType="com.jwt.entity.User" resultType="com.jwt.entity.User">
        SELECT * FROM user WHERE username = #{username} AND password = #{password}
    </select>

</mapper>

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

/**
 * 配置拦截器
 */
public class JWTInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Map<String, Object> map = new HashMap<>();

        //获取请求头中的令牌
        String token = request.getHeader("token");

        try {
            //验证令牌
            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;
    }
}

编写InterceptorConfig类:

/**
 * 注册拦截器
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new JWTInterceptor())
                //拦截
                .addPathPatterns("/user/test")
                //放行
                .excludePathPatterns("/user/login");
    }
}

4、测试

运行程序后,使用postman进行测试,登录如下图
请求方式:get
url:http://localhost:8899/user/login?username=zhangsan&password=123
然后点击send,就会看到返回成功和token

请求测试
请求方式:post
url:http://localhost:8899/user/test
点击header,在请求头中添加token,然后点击send

到此这篇关于Spring Boot整合JWT的文章就介绍到这了,更多相关Spring Boot整合JWT内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot整合JWT的入门指南

    目录 1.JWT 2.JWT登录执行流程图 3.为什么使用JWT? 4.JWT的组成 5.SpringBoot整合JWT 测试 总结 1.JWT JWT(JSON Web Token),为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准.将用户信息加密到token中,服务器不保存任何用户信息,服务器通过保存的密钥验证token的正确性. 优点 1.简介:可以通过 URL POST 参数或者在 HTTP header 发送,因为数据量小,传输速度也很快: 2.自包含:负载中可以包含用户

  • SpringBoot Security整合JWT授权RestAPI的实现

    本教程主要详细讲解SpringBoot Security整合JWT授权RestAPI. 基础环境 技术 版本 Java 1.8+ SpringBoot 2.x.x Security 5.x JWT 0.9.0 创建项目 初始化项目 mvn archetype:generate -DgroupId=com.edurt.sli.slisj -DartifactId=spring-learn-integration-security-jwt -DarchetypeArtifactId=maven-ar

  • Springboot实现Shiro整合JWT的示例代码

    写在前面 之前想尝试把JWT和Shiro结合到一起,但是在网上查了些博客,也没太有看懂,所以就自己重新研究了一下Shiro的工作机制,然后自己想了个(傻逼)办法把JWT和Shiro整合到一起了 另外接下来还会涉及到JWT相关的内容,我之前写过一篇博客,可以看这里:Springboot实现JWT认证 Shiro的Session机制 由于我的方法是改变了Shiro的默认的Session机制,所以这里先简单讲一下Shiro的机制,简单了解Shiro是怎么确定每次访问的是哪个用户的 Servlet的Se

  • SpringBoot整合JWT框架,解决Token跨域验证问题

    一.传统Session认证 1.认证过程 1.用户向服务器发送用户名和密码. 2.服务器验证后在当前对话(session)保存相关数据. 3.服务器向返回sessionId,写入客户端 Cookie. 4.客户端每次请求,需要通过 Cookie,将 sessionId 回传服务器. 5.服务器收到 sessionId,验证客户端. 2.存在问题 1.session保存在服务端,客户端访问高并发时,服务端压力大. 2.扩展性差,服务器集群,就需要 session 数据共享. 二.JWT简介 JWT

  • Spring Boot整合JWT的实现步骤

    springboot整合jwt步骤: 1.登录时,验证账号和密码成功后,生成jwt,返回给前端: 2.前端接收后保存,再做其他操作,比如增删改查时,同时将jwt传给后端进行验证,如果jwt当做参数一起传给后端,那么每个操作都会有jwt,为了方便,把jwt放到请求头中,通过拦截器来验证. 代码 代码结构图如下,除了常规的controller.entity.mapper和service层,还有两个拦截器和注册拦截器,图中用红字进行注释(这篇文章稍微有点长,因为我把代码都放上来了,结合下边的思路和结构

  • Spring Boot 整合 JWT的方法

    1.JWT 是什么? JWT 是一个开放标准,它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法.JWT 可以使用 HMAC 算法或者是 RSA 的公钥密钥对进行签名. 简单来说,就是通过一定规范来生成 token,然后可以通过解密算法逆向解密 token,这样就可以获取用户信息. 优点: 1)生产的 token 可以包含基本信息,比如 id.用户昵称.头像等信息,避免再次查库 2)存储在客户端,不占用服务端的内存资源 缺点: token 是经过 base6

  • Spring Boot 整合单机websocket的步骤 附github源码

    websocket 概念 websocket 是一个通信协议,通过单个 TCP 连接提供全双工通信.websocket 连接成功后,服务端和客户可以进行双向通信.不同于 http 通信协议需要每次由客户端发起,服务响应到客户端. websocket 相对轮询也能节约带宽,并且能实时的进行通信. 整合步骤 1. 添加 maven 依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifact

  • Spring Boot整合Redis的完整步骤

    前言 实际 开发 中 缓存 处理是必须的,不可能我们每次客户端去请求一次 服务器 ,服务器每次都要去 数据库 中进行查找,为什么要使用缓存?说到底是为了提高系统的运行速度.将用户频繁访问的内容存放在离用户最近,访问速度最 快的 地方,提高用户的响 应速度,今天先来讲下在 springboot 中整合 redis 的详细步骤. 一.Spring Boot对Redis的支持 Spring对Redis的支持是使用Spring Data Redis来实现的,一般使用Jedis或者lettuce(默认),

  • Spring Boot整合elasticsearch的详细步骤

    一.简介 我们的应用经常需要添加检索功能,开源的 ElasticSearch 是目前全文搜索引擎的 首选.他可以快速的存储.搜索和分析海量数据.Spring Boot通过整合Spring Data ElasticSearch为我们提供了非常便捷的检索功能支持; Elasticsearch是一个分布式搜索服务,提供Restful API,底层基于Lucene,采用 多shard(分片)的方式保证数据安全,并且提供自动resharding的功能,github 等大型的站点也是采用了ElasticSe

  • Spring Boot整合Swagger2的完整步骤详解

    前言 swagger,中文"拽"的意思.它是一个功能强大的api框架,它的集成非常简单,不仅提供了在线文档的查阅, 而且还提供了在线文档的测试.另外swagger很容易构建restful风格的api. 一.Swagger概述 Swagger是一组围绕OpenAPI规范构建的开源工具,可帮助设计.构建.记录和使用REST API. 简单说下,它的出现就是为了方便进行测试后台的restful形式的接口,实现动态的更新,当我们在后台的接口 修改了后,swagger可以实现自动的更新,而不需要

  • Spring Boot整合MyBatis连接Oracle数据库的步骤全纪录

    前言 本文主要分享了Spring Boot整合MyBatis连接Oracle数据库的相关内容,下面话不多说了,直接来详细的步骤吧. 步骤如下: 1.Spring Boot项目添加MyBatis依赖和Oracle驱动: <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <ver

  • Spring boot整合Mybatis实现级联一对多CRUD操作的完整步骤

    前言 在关系型数据库中,随处可见表之间的连接,对级联的表进行增删改查也是程序员必备的基础技能.关于Spring Boot整合Mybatis在之前已经详细写过,不熟悉的可以回顾Spring Boot整合Mybatis并完成CRUD操作,这是本文操作的基础.本文先准备一个测试的数据库,然后使用MyBatis Generator进行部分代码自动生成,再以一个例子来展示稍微高级点的操作:使用Mybatis完成级联一对多的CRUD操作. 数据库准备 数据库用到三张表:user表,role表,user_ro

  • Spring boot整合shiro+jwt实现前后端分离

    本文实例为大家分享了Spring boot整合shiro+jwt实现前后端分离的具体代码,供大家参考,具体内容如下 这里内容很少很多都为贴的代码,具体内容我经过了看源码和帖子加了注释.帖子就没用太多的内容 先下载shiro和jwt的jar包 <!-- shiro包 --> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId

  • Spring Boot整合EhCache的步骤详解

    本文讲解Spring Boot与EhCache的整合. 1 EhCache简介 EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认CacheProvider.Ehcache是一种广泛使用的开源Java分布式缓存.主要面向通用缓存,Java EE和轻量级容器.它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点. 2 Spring Boot整合EhCache步骤 2.

随机推荐