美文网首页后端技术Code
Spring boot整合JWT实现登入认证

Spring boot整合JWT实现登入认证

作者: 幽灵邀请函 | 来源:发表于2021-02-02 23:35 被阅读0次

    Spring boot整合JWT实现登入认证

    有一项技能可能改变你一生

    之前分享了使用shiro实现登入认证,我们也可以使用jwt来实现这一功能

    springboot整合jwt

    pom.xml添加依赖

    <dependencies>
    
            <dependency>
                <groupId>com.auth0</groupId>
                <artifactId>java-jwt</artifactId>
                <version>3.4.0</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.1.2</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.22</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </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>
        </dependencies>
    
    

    创建user表

    CREATE TABLE `user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(30) DEFAULT NULL,
      `password` varchar(64) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    
    

    创建user实体类

    package com.example.springbootjwt.entity;
    
    /**
     * @author kalvin
     * @version 1.0
     * @Date 2021/2/2 10:15
     * @Description
     **/
    import lombok.Data;
    import lombok.experimental.Accessors;
    
    @Data
    @Accessors(chain=true)
    public class User {
        private String id;
        private String name;
        private String password;
    }
    

    创建userDao

    package com.example.springbootjwt.dao;
    
    import com.example.springbootjwt.entity.User;
    import org.apache.ibatis.annotations.Mapper;
    
    @Mapper
    public interface UserDao {
       User login(User user);
    }
    

    创建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.example.springbootjwt.dao.UserDao">
        <select id="login" parameterType="User" resultType="User">
            select * from user where name= #{name} and password= #{password}
        </select>
    </mapper>
    

    创建UserService

    package com.example.springbootjwt.service;
    
    import com.example.springbootjwt.entity.User;
    
    public interface UserService {
        User login(User user);
    }
    

    创建UserServiceImpl

    package com.example.springbootjwt.service;
    
    import com.example.springbootjwt.dao.UserDao;
    import com.example.springbootjwt.entity.User;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    /**
     * @author kalvin
     * @version 1.0
     * @Date 2021/2/2 10:19
     * @Description
     **/
    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDao userDao;
    
        @Override
        public User login(User user) {
            User user1 = userDao.login(user);
            if(user1!=null){
                return user1;
            }
            throw new RuntimeException("认证失败!");
        }
    }
    

    自定义JWTInterceptor继承HandlerInterceptor

    package com.example.springbootjwt.interceptor;
    
    import com.auth0.jwt.exceptions.AlgorithmMismatchException;
    import com.auth0.jwt.exceptions.SignatureVerificationException;
    import com.auth0.jwt.exceptions.TokenExpiredException;
    import com.example.springbootjwt.utils.JWTUtils;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author kalvin
     * @version 1.0
     * @Date 2021/2/2 10:27
     * @Description
     **/
    public class JWTInterceptor implements HandlerInterceptor {
    
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            //获取请求头中的token
            String token = request.getHeader("token");
            Map<String,Object> map = new HashMap<String, Object>();
            try {
                JWTUtils.TokenVerify(token);
                //放行请求
                return true;
            } catch (SignatureVerificationException e) {
                map.put("msg", "无效签名");
                e.printStackTrace();
            } catch (TokenExpiredException e) {
                map.put("msg", "token已过期");
                e.printStackTrace();
            } catch (AlgorithmMismatchException e) {
                map.put("msg", "算法不一致");
                e.printStackTrace();
            } catch (Exception e) {
                map.put("msg", "token无效");
                e.printStackTrace();
            }
            map.put("state",false);
            //使用jackson将map转为json
            String json = new ObjectMapper().writeValueAsString(map);
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().print(json);
            return false;
        }
    
    }
    

    编写InterceptorConfig实现WebMvcConfigurer

    package com.example.springbootjwt.config;
    
    import com.example.springbootjwt.interceptor.JWTInterceptor;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    /**
     * @author kalvin
     * @version 1.0
     * @Date 2021/2/2 10:30
     * @Description
     **/
    @Configuration
    public class InterceptorConfig implements WebMvcConfigurer {
    
        public void addInterceptors(InterceptorRegistry registry) {
            //注册拦截器JWTInterceptor,对用户名密码登入进行权限验证
            registry.addInterceptor(new JWTInterceptor())
                    //指定拦截器注册拦截器JWTInterceptor要拦截的请求(支持*通配符)
                    .addPathPatterns("/**")
                    //指定拦截器JWTInterceptor不拦截的请求(支持*通配符)
                    .excludePathPatterns("/user/login");
        }
    }
    

    创建jwt工具

    package com.example.springbootjwt.utils;
    import java.util.Calendar;
    import java.util.Map;
    
    import com.auth0.jwt.JWT;
    import com.auth0.jwt.JWTCreator;
    import com.auth0.jwt.algorithms.Algorithm;
    import com.auth0.jwt.interfaces.DecodedJWT;
    /**
     * @author kalvin
     * @version 1.0
     * @Date 2021/2/2 10:24
     * @Description
     **/
    public class JWTUtils {
    
        private static final String SIGN= "!@#$%^&*123456789";
    
    
        /**
         * 生成Token
         */
        public static String getToken(Map<String,String> map) {
            Calendar instance = Calendar.getInstance();
            instance.add(Calendar.DATE, 7);
            //创建JWTBuilder
            JWTCreator.Builder builder = JWT.create();
            //设置payload
            map.forEach((k,v)->{
                builder.withClaim(k, v);
            });
            //设置过期时间和签名,生成token
            String token = builder.withExpiresAt(instance.getTime())
                    .sign(Algorithm.HMAC256(SIGN));
            return token;
        }
    
        /**
         * 验证token
         */
        public static void TokenVerify(String token) {
            JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
        }
    
        /**
         * 获取token信息
         */
        public static DecodedJWT getTokenInfo(String token) {
            DecodedJWT verify = JWT.require(Algorithm.HMAC256(SIGN)).build().verify(token);
            return verify;
        }
    
    }
    

    最后怎能少了我们的userController

    package com.example.springbootjwt.controller;
    
    import com.auth0.jwt.interfaces.DecodedJWT;
    import com.example.springbootjwt.entity.User;
    import com.example.springbootjwt.service.UserServiceImpl;
    import com.example.springbootjwt.utils.JWTUtils;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpServletRequest;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author kalvin
     * @version 1.0
     * @Date 2021/2/2 10:31
     * @Description
     **/
    @RestController
    @Slf4j
    public class UserController {
    
        @Autowired
        private UserServiceImpl userServiceImpl;
    
        @GetMapping("/user/login")
        public Map<String,Object> login(User user){
            log.info("用户名:[{}]",user.getName());
            log.info("密码:[{}]",user.getPassword());
            Map<String,Object> map = new HashMap<String, Object>();
            try {
                User userDB = userServiceImpl.login(user);
                Map<String,String> payload = new HashMap<String, String>();
                payload.put("id", userDB.getId());
                payload.put("name", userDB.getName());
                String token = JWTUtils.getToken(payload);
                map.put("state",true);
                map.put("msg","认证成功");
                map.put("token", token);
            } catch (Exception e) {
                map.put("state",false);
                map.put("msg",e.getMessage());
            }
            return map;
        }
    
        @PostMapping("/user/test")
        public Map<String,Object> test(HttpServletRequest request){
    
            String token = request.getHeader("token");
    
            DecodedJWT tokenInfo = JWTUtils.getTokenInfo(token);
            log.info("用户id:[{}]",tokenInfo.getClaim("id").asString());
            log.info("用户名:[{}]",tokenInfo.getClaim("name").asString());
            Map<String,Object> map = new HashMap<String, Object>();
            map.put("state", true);
            map.put("msg","请求成功");
            return map;
        }
    
    }
    

    大致的项目结构如下:

    image.png

    到此运行一下吧,看看你成功了没?相信你都成功了吧!我学习一个新知识比较喜欢先写一个demo跑起来了再去理解会更轻松点,哈哈哈。

    image.png
    错误演示
    image.png
    完整项目代码获取途径:微信公众号 幽灵邀请函 回复 jwt

    相关文章

      网友评论

        本文标题:Spring boot整合JWT实现登入认证

        本文链接:https://www.haomeiwen.com/subject/miwutltx.html