springboot整合jwt(一)

背景:应项目组要求,以后需整合cs、bs、app等,使用jwt作为权限验证

官网 :https://jwt.io/

GitHub:https://github.com/jwtk/jjwt

other: https://blog.usejournal.com/sessionless-authentication-withe-jwts-with-node-express-passport-js-69b059e4b22c

https://github.com/dwyl/learn-json-web-tokens/blob/master/README.md

一、什么是JWT(JSON Web Token)

1.JWT是一个开放标准(RFC 7519)

2.JWT定义了一种紧凑且独立的方式,用于在各方之间作为JSON对象安全地传输信息

3.JWT传输信息通过数字签名进行验证和信任

4.JWT可以使用秘密(使用HMAC算法)或使用RSAECDSA的公钥/私钥对进行签名

二、什么时候使用JWT(JSON Web Tokens)

1. 授权:允许用户访问该令牌允许的路由,服务和资源

2.信息交换:安全传输信息

三、JWT(JSON Web Token)结构

1. JWT由dots (.)分隔得三个部分组成:头部元素(Header)、有效载荷(Payload)、签名(Signature)

2. 对应的格式:xxxxx.yyyyy.zzzzz

3. 头部:头部一般由token类型(即JWT)、正在使用的签名算法(如:HMAC SHA256或RSA)

头部元素案例:

{
  "alg": "HS256",
  "typ": "JWT"
}

4.有效载荷:包含声明(注:声明只有三个字符),是关于实体(通常是用户)和其他数据的声明,有效负载最终会经过Base64Url编码

声明有三种类型:已注册的声明、公开声明、私有声明

已注册的声明:是预定义的、非强制性的,一般建议使用,用来提供一组有用的、可互操作的声明,如:iss(发行人), exp(到期时间),(主题), aud(观众)等

公开声明:可以随意定义,但是为了避免冲突,应该在 IANA JSON Web Token Registry中定义,或者将其定义为包含冲突命名空间的URI

私有声明:是为了在双方之间共享信息而创建的自定义声明

有效载荷案例:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

 注:对于已签名的令牌,尽管这些信息受到保护以防篡改,但任何人都可以读取。除非JWT是加密的,否则不要将机密信息放在它的有效载荷或头元素中。

签名:要创建签名部分,必须获取编码的头部元素、编码的有效负载、密码、头部元素指定的算法,并对其进行签名

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

 JWT解密地址:jwt.io Debugger ,下面是官方提供的JWT解码案例

springboot整合jwt(一)_第1张图片

四、JWT(JSON Web Tokens )如何工作

1. 在身份验证中,当用户使用凭证成功登陆后,将返回JWT(JSON Web Token)并且必须在本地保存(通常在本地存储中,但也可以使用cookie),而不是传统的在服务器创建会话并返回一个cookie的方法。

2. 由于token是重要的凭证,所以必须非常小心,以防止出现安全问题

3. 一般情况下,token保留时长不要超过要求的时间

4. 当用户想要访问受保护的路由或资源时,用户代理应该使用承载(Bearer)模式发送JWT,header应如下所示

Authorization: Bearer 

5. 在某些情况下,这可以是无状态授权机制。服务器的受保护路由将检查Authorization header中是否存在有效的JWT,如果存在,则允许用户访问受保护的资源。如果JWT包含必要的数据,则可以减少查询数据库以进行某些操作的需要,尽管可能并非总是如此。

6. 如果在Authorization header中发送token,则跨域资源共享(CORS)将不会成为问题,因为它不使用cookie。

下图显示了如何获取JWT并用于访问API或资源:

JSON Web令çå¦ä½å·¥ä½

  1. 应用程序或客户端向授权服务器请求授权。这是通过其中一个不同的授权流程执行的。
  2. 授权后,授权服务器会向应用程序返回访问令牌(token)。
  3. 应用程序使用访问令牌(token)来访问受保护资源(如API)。

五、为什么要使用JWT(JSON Web Tokens)

1. 由于JSON比XML更简洁,因此在编码时它的大小也更小,使得JWT比SAML(Simple Web Tokens)更紧凑

2. 在安全方面,SWT只能使用HMAC算法通过共享密钥对称签名。但是,JWT和SAML令牌可以使用X.509证书形式的公钥/私钥对进行签名。与签名JSON的简单性相比,使用XML数字签名对XML进行签名而不会引入模糊的安全漏洞非常困难。

3. JSON解析器在大多数编程语言中很常见,因为它们直接映射到对象,相反,XML没有自然的文档到对象映射,这使得使用JWT比使用SAML断言更容易。

4.  关于使用,JWT在互联网的使用,突出了在多个平台(尤其是移动平台)上客户端处理JWT(JSON Web token)的便利性。

六、如何使用JWT

1. 创建一个简单的maven工程,pom文件依赖如下


       org.springframework.boot
       spring-boot-starter-parent
       2.1.4.RELEASE
       
   
  
    
        org.springframework.boot
        spring-boot-starter-web
    
    
    
	    io.jsonwebtoken
	    jjwt-api
	    ${jjwt.version}
	
	
	    io.jsonwebtoken
	    jjwt-impl
	    ${jjwt.version}
	    runtime
	
	
	    io.jsonwebtoken
	    jjwt-jackson
	    ${jjwt.version}
	    runtime
	
	
    
        org.junit.platform
        junit-platform-launcher
        test
    
    
        org.junit.jupiter
        junit-jupiter-engine
        test
    
  

2. 创建测试类JWTTest.java

package com.hegret.test;

import java.security.Key;
import java.util.Date;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import org.junit.jupiter.api.Test;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

public class JWTTest {

//    @Test
//    void test() {
//        String header = "{\"alg\":\"HS256\"}";
//        String claims = "{\"sub\":\"Joe\"}";
//        String encodedHeader = base64URLEncode(header.getBytes("UTF-8"));
//        String encodedClaims = base64URLEncode(claims.getBytes("UTF-8"));
//        String concatenated = encodedHeader + '.' + encodedClaims;
//        Key key = getMySecretKey()
//        byte[] signature = hmacSha256(concatenated, key);
//        String jws = concatenated + '.' + base64URLEncode(signature);
//    }

    @Test
    void testCreateJWTAndParseJWT() {
        String token = createJWT("1", "myCompany", "zhangsan", 10000);
        System.out.println(token);
        parseJWT(token);
    }
    
    @Test
    void testTtlMillis() throws InterruptedException {
        String token = createJWT("1", "myCompany", "zhangsan", 10000);
        System.out.println(token);
        Thread.sleep(10000);
        parseJWT(token);    
    }

    // Sample method to construct a JWT
    private String createJWT(String id, String issuer, String subject, long ttlMillis) {

        // The JWT signature algorithm we will be using to sign the token
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);

        // We will sign our JWT with our ApiKey secret
//        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(apiKey.getSecret());
        byte[] apiKeySecretBytes = DatatypeConverter
                .parseBase64Binary("mySecretaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbcccccccb");
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        // Let's set the JWT Claims
        JwtBuilder builder = Jwts.builder().setId(id).setIssuedAt(now).setSubject(subject).setIssuer(issuer)
                .signWith(signingKey);
//                .signWith(signingKey, signatureAlgorithm);

        // if it has been specified, let's add the expiration
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }

        // Builds the JWT and serializes it to a compact, URL-safe string
        return builder.compact();
    }

    // Sample method to validate and read the JWT
    private void parseJWT(String jwt) {

        // This line will throw an exception if it is not a signed JWS (as expected)
//        Claims claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(apiKey.getSecret()))
        Claims claims = Jwts.parser()
                .setSigningKey(DatatypeConverter.parseBase64Binary("mySecretaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbcccccccb"))
                .parseClaimsJws(jwt).getBody();
        System.out.println("ID: " + claims.getId());
        System.out.println("Subject: " + claims.getSubject());
        System.out.println("Issuer: " + claims.getIssuer());
        System.out.println("Expiration: " + claims.getExpiration());
    }
}

3.运行测试方法testCreateJWTAndParseJWT,结果显示如下,表示创建token和token验证成功

eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxIiwiaWF0IjoxNTYxNDU2ODAxLCJzdWIiOiJ6aGFuZ3NhbiIsImlzcyI6Im15Q29tcGFueSIsImV4cCI6MTU2MTQ1NjgxMX0.EyAYyTAFXTK04P3sYfQn8rlRngSswQT_1p9DEWphyyU
ID: 1
Subject: zhangsan
Issuer: myCompany
Expiration: Tue Jun 25 18:00:11 CST 2019

4. 运行测试方法createJWT,结果显示如下,从结果可以看出,token失效后,再进行验证不通过

eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiIxIiwiaWF0IjoxNTYxNDU2OTU3LCJzdWIiOiJ6aGFuZ3NhbiIsImlzcyI6Im15Q29tcGFueSIsImV4cCI6MTU2MTQ1Njk2N30.TaCgyoXQRhATLPNeo_pKfX80WXZ8tv1Vw6lph_Wfj0Q
io.jsonwebtoken.ExpiredJwtException: JWT expired at 2019-06-25T10:02:47Z. Current time: 2019-06-25T10:02:48Z, a difference of 1234 milliseconds.  Allowed clock skew: 0 milliseconds.
	at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:411)
	at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:513)
	at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:573)
	at com.hegret.test.JWTTest.parseJWT(JWTTest.java:83)
	at com.hegret.test.JWTTest.testTtlMillis(JWTTest.java:42)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:628)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:117)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:184)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:180)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:127)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:137)
	at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:89)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)

测试案例到此结束

七、通过http请求方式来验证

1. 在上面的基础上引入mysql驱动、数据库连接池HikariCP、mybatis依赖

 
        
            mysql
            mysql-connector-java
            runtime
        
        
        
            com.zaxxer
            HikariCP
        
         
            org.mybatis.spring.boot
            mybatis-spring-boot-starter
            2.0.1
        

2. 在项目资源文件夹src/main/resources下创建application.yml文件,内容如下:

debug:
  true
spring:
  datasource:
    username: root
    password: 1234
    url: jdbc:mysql://127.0.0.1:3306/jwt?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      maximum-pool-size: 20
      max-lifetime: 1800000
      idle-timeout: 30000
      data-source-properties:
        prepStmtCacheSize: 250
        prepStmtCacheSqlLimit: 2048
        cachePrepStmts: true
        useServerPrepStmts: true

 3. 创建用户实体类User.java

package com.hegret.entity;

import java.io.Serializable;

public class User implements Serializable {

    private static final long serialVersionUID = 1L;
    
    private String id;
    private String name;
    private String password;
    private String email;

    public String getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", password=" + password + ", email=" + email + "]";
    }
    
    

}

4. 创建UserDao接口 

package com.hegret.dao;

import org.springframework.stereotype.Repository;

import com.hegret.entity.User;

@Repository
public interface UserDao {
    User findByName(String name);
}

5. 在src/main/resources/mybatis/mapper目录下添加user-mapper.xml文件,内容如下:





    

6. 在application.yml文件中添加mapper映射文件读取路径

mybatis:
  mapper-locations: classpath:mybatis/mapper/*-mapper.xml

7. 编写启动器引导类,并添加dao接口注解扫描

package com.hegret;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@MapperScan(value = "com.hegret.dao")
@SpringBootApplication
public class JWTApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(JWTApplication.class, args);
    }
}

8. 编写UserService业务接口

package com.hegret.service;

import com.hegret.entity.User;

public interface UserService {
    
    User getByName(String name);
}

9. 编写实现类UserServiceImpl.java

package com.hegret.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.hegret.dao.UserDao;
import com.hegret.entity.User;
import com.hegret.service.UserService;

@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserDao userDao;

    @Override
    public User getByName(String name) {
        return userDao.findByName(name);
    }

}

10. 自定义异常类CustomException

package com.hegret.exception;

import com.hegret.enums.CodeMsgEnum;

public class CustomException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    private CodeMsgEnum codeMsg;

    public CustomException(CodeMsgEnum codeMsg) {
        this.codeMsg = codeMsg;
    }

    public CodeMsgEnum getCodeMsg() {
        return codeMsg;
    }

}

11. 自定义结果类型JsonResult.java

package com.hegret.util;

import java.io.Serializable;

import com.hegret.enums.CodeMsgEnum;

public class JsonResult implements Serializable {

    private static final long serialVersionUID = 1L;

    private static final int SUCCESS_CODE = 200;
    private static final String SUCCESS_MSG = "success";

    private int code;
    private String msg;
    private T data;

    public static  JsonResult error(CodeMsgEnum codeMsg) {
        return new JsonResult(codeMsg);
    }

    public static  JsonResult success(T data) {
        return new JsonResult(data);
    }

    public static  JsonResult success() {
        return new JsonResult();
    }

    private JsonResult() {
        this.code = SUCCESS_CODE;
        this.msg = SUCCESS_MSG;
    }

    private JsonResult(T data) {
        this.code = SUCCESS_CODE;
        this.msg = SUCCESS_MSG;
        this.data = data;
    }

    private JsonResult(CodeMsgEnum codeMsg) {
        this.code = codeMsg.getCode();
        this.msg = codeMsg.getMsg();
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public T getData() {
        return data;
    }

    @Override
    public String toString() {
        return "JsonResult [code=" + code + ", msg=" + msg + ", data=" + data + "]";
    }

}

12. 定义CodeMsg枚举类

package com.hegret.enums;

public enum CodeMsgEnum {

    USERNAME_OR_PASSWORD_ERROR(500100, "用户名或密码错误"),
    UNKNOWN_ERROR(500200, "发生未知错误,请联系管理员");

    private final Integer code;
    private final String msg;

    private CodeMsgEnum(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

}

13. 统一异常处理

package com.hegret.handler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hegret.enums.CodeMsgEnum;
import com.hegret.exception.CustomException;
import com.hegret.util.JsonResult;

@ControllerAdvice
@ResponseBody
public class WebExceptionHandler {

    Logger logger = LoggerFactory.getLogger(getClass());

    @ExceptionHandler
    public JsonResult usernameOrPasswordError(CustomException e) {
        logger.error(e.getCodeMsg().toString());
        return JsonResult.error(e.getCodeMsg());
    }

    @ExceptionHandler
    public JsonResult unknownException(Exception e) {
        logger.error("发生了未知异常", e);
        // 发送邮件通知技术人员.
        return JsonResult.error(CodeMsgEnum.UNKNOWN_ERROR);
    }
}

14. 编写api控制器类UserController.java

package com.hegret.api.controller;

import java.security.Key;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.hegret.entity.User;
import com.hegret.enums.CodeMsgEnum;
import com.hegret.exception.CustomException;
import com.hegret.service.UserService;
import com.hegret.util.JsonResult;

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

@RestController
@RequestMapping("/user")
public class UserController {
    
    private volatile Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
    
    @Autowired
    private UserService userService;
    
    @PostMapping("/sessions")
    public JsonResult> login(@RequestBody User user) {
        if(user == null || StringUtils.isEmpty(user.getName()) || StringUtils.isEmpty(user.getName())) {
            throw new CustomException(CodeMsgEnum.USERNAME_OR_PASSWORD_NOT_EMPTY);
        }
        User user2 = userService.getByName(user.getName());
        if (user2 == null || !user.getPassword().equals(user2.getPassword())) {
            throw new CustomException(CodeMsgEnum.USERNAME_OR_PASSWORD_ERROR);
        }
        String jws = Jwts.builder().setId(user.getId()).setSubject(user.getName()).signWith(key).compact();
        Map map = new HashMap();
        map.put("token", jws);
        return JsonResult.success (map);
    }
    
    @PostMapping("/info")
    public JsonResult get(HttpServletRequest request) throws Exception {
        Enumeration authorizations = request.getHeaders("Authorization");
        String authorization = null;
        while (authorizations.hasMoreElements()) {
            authorization = (String) authorizations.nextElement();
            System.out.println("authorization=========" + authorization);
            if (authorization.matches("(Bearer )[\\d\\D]*")) {
                break;
            }
            
        }
        if (StringUtils.isEmpty(authorization)) {
            throw new CustomException(CodeMsgEnum.TOKEN_NOT_EMPTY);
        }
        String token = authorization.replace("Bearer ", "");
        if (StringUtils.isEmpty(token)) {
            throw new CustomException(CodeMsgEnum.TOKEN_NOT_EMPTY);
        }
        Object obj = Jwts.parser().setSigningKey(key).parseClaimsJws(token);
        return JsonResult.success (obj);
    }
}
 
  

15. 打开post,发送post请求http://localhost:8080/user/sessions

springboot整合jwt(一)_第2张图片

16.发送post请求http://localhost:8080/user/info

springboot整合jwt(一)_第3张图片

从结果可以看出通过http方式验证成功 

你可能感兴趣的:(springboot整合jwt(一))