简单的基于jwt 的token验证实现

之前一直使用的是cookie session的方式进行接口访问的判断,后续在换架构之后使用分布式springcloud搭建项目,接触了token的接口权限校验感觉还不错所以记录一下。

首先来看一下目录结构

 

 首先需要用的的环境是jdk8及以上,maven,关系型数据库。

开始创建一个maven项目

下面是需要用到的依赖(依赖下不到的可以百度)

<dependencies>
    <!--引入jwt依赖-->
    <dependency>
        <groupId>com.auth0</groupId>
        <artifactId>java-jwt</artifactId>
        <version>3.4.1</version>
    </dependency>

    <!--        引入mybatis-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.0.1</version>
    </dependency>

    <!--mysql驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>

    <!--lombok-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.22</version>
        <optional>true</optional>
    </dependency>
    <!--        web依赖-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

 

 接下来是jwt的工具类

package com.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
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.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

public class JwtUtils {
    //密钥(设置一个比较复杂的)
    private static final String SING = "123456";
    /**
     * 生成token
     */
    public static String getToken(Map<String,String> map) {
        Calendar instance = Calendar.getInstance();
        //默认7天过期
//        instance.add(Calendar.DATE, 7);
        //这里设置3min过期
        instance.add(Calendar.MINUTE, 3);
        //创建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);
    }

}

 拦截器,用来拦截是否需要携带token请求头请求接口

package com.config;
import com.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("/**")
                //放行
                .excludePathPatterns("/user/login");
    }
}

token校验后的错误码返回拦截器

package com.interceptor;

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.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import com.utils.JwtUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class JwtInterceptor implements HandlerInterceptor {
    private static final Logger log = LoggerFactory.getLogger(JwtInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        Map<String, Object> 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",false);
        //将map转为json
        String json = new ObjectMapper().writeValueAsString(map);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
        return false;
    }
}

用户的实体

package com.pojo;

public class User {
    private String id;
    private String username;
    private String password;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

写一个用于测试的controller试试吧!

package com.controller;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 com.pojo.User;
import com.service.UserService;
import com.utils.JwtUtils;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

@RestController
public class UserController {
    private static final Logger log = LoggerFactory.getLogger(UserController.class);
    @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);
            User userDB =new User();
            userDB.setUsername("admin");
            userDB.setId("1001");
            Map<String, String> payload = new HashMap<>();
            //用户登录成功后的信息放入payload
            payload.put("id", userDB.getId());
            payload.put("username", userDB.getUsername());
            //生成JWT令牌,提示token加密方式是base64所以不要再token中存放敏感信息
            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> test1(String token){
        Map<String, Object> map = new HashMap<>();
        map.put("msg","访问成功!!!");
        return map;
    }
}

结果成功!

下面试试被token拦截的请求在不带token的情况下请求的返回结果

 

  这个是token过期的情况

 

 token验证成功的情况

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
JWT(JSON Web Token)是一种基于 JSON 的开放标准(RFC 7519),用于在各方之间安全地将声明作为 JSON 对象传输。JWT通常用于身份验证和授权。JWT由三部分组成:头部、载荷和签名。 在使用 JWT 进行身份验证时,服务器会在用户登录成功后生成一个 JWT,并将其发送给客户端。客户端将 JWT 存储在本地,每次向服务器发送请求时,都需要在请求头中携带该 JWT。服务器在接收到请求后,会验证JWT 的有效性,并根据 JWT 中的信息进行相应的处理。 JWT 的优点是可以减轻服务器的压力,因为服务器不需要在每次请求时都去查询数据库进行身份验证。同时,由于 JWT 中已经包含了足够的信息,服务器可以快速地进行权限验证和授权。 如果要实现 JWT 的登录验证,可以按照以下步骤进行: 1. 用户在登录成功后,服务器生成一个 JWT,并将其发送给客户端。 2. 客户端将 JWT 存储在本地,例如在 LocalStorage 或者 Cookie 中。 3. 客户端在向服务器发送请求时,需要在请求头中携带该 JWT。 4. 服务器在接收到请求后,需要验证JWT 的有效性。服务器可以根据 JWT 的头部信息,结合自己的密钥对 JWT 进行解密,验证 JWT 的签名是否正确。 5. 如果 JWT 验证通过,则说明当前用户已经登录。服务器可以根据 JWT 中的信息,进行相应的权限验证和授权。 需要注意的是,JWT 中的信息是可以被解密的,因此在 JWT 中不应该存储敏感信息,例如用户的密码等。如果需要存储敏感信息,可以考虑使用加密算法对其进行加密。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值