zoukankan      html  css  js  c++  java
  • jwt的简单使用

    简介

    使用jwt对数据进行存储加密,分为java和golang版本。


    java版本

    • maven配置

      <dependency>
          <groupId>com.auth0</groupId>
          <artifactId>java-jwt</artifactId>
          <version>3.4.0</version>
      </dependency>
      
    • 工具类 JWTUtil.java

      import com.auth0.jwt.JWT;
      import com.auth0.jwt.JWTVerifier;
      import com.auth0.jwt.algorithms.Algorithm;
      import com.auth0.jwt.interfaces.DecodedJWT;
      import lombok.Getter;
      import org.springframework.boot.context.properties.ConfigurationProperties;
      import org.springframework.stereotype.Component;
      
      import java.util.Date;
      
      public class JWTUtil {
      
          private final static String ISS = "dust";
      
          private final static String SECRET = "secret";
      
          // 过期时间是3600秒,既是1个小时
          private final static long EXPIRATION = 3600;
      
      
          /**
           * 生成token
           * @param userId 用户id
           * @return token
           */
          public static String createToken(long userId){
              Algorithm algorithm = Algorithm.HMAC384(SECRET);
              String token = JWT.create()
            			.withIssuer(ISS).withIssuedAt(new Date()).withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION * 1000))
                      .withClaim("USER_ID",userId)
                      .sign(algorithm);
      
              return token;
          }
      
          /**
           * 解析token
           * @param token token
           * @return long
           */
          public static long analyzeToken(String token){
              DecodedJWT decode = JWT.decode(token);
              return decode.getClaim("USER_ID").asLong();
          }
      
          /**
           * 校验token的合法性
           * @param token token
           * @return  boolean
           */
          public static boolean verifyToken(String token){
              Algorithm algorithm = Algorithm.HMAC384(SECRET);
              JWTVerifier verifier = JWT.require(algorithm)
                      .withIssuer(ISS)
                      .build(); //Reusable verifier instance
              try {
                  // 验证不通过会出现异常
                  verifier.verify(token);
              } catch(Exception ex){
                  return false;
              }
              return true;
          }
      
      }
      
    • 测试 JWTTests.java

      import org.junit.Test;
      public class JWTTests {
          @Test
          public void createTokenTest(){
              String token = JwtUtil.createToken(12345678);
              System.out.println(token); // eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpc3MiOiJkdXN0IiwiVVNFUl9JRCI6MTIzNDU2Nzh9.qUNgiHKB5uIWhhpf8GM6hdcaE9hTvDJG9UmmMpcCPpfncduQ713aKI7VMhCedJWP
          }
      
          @Test
          public void decodeTokenTest(){
              String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpc3MiOiJkdXN0IiwiVVNFUl9JRCI6MTIzNDU2Nzh9.qUNgiHKB5uIWhhpf8GM6hdcaE9hTvDJG9UmmMpcCPpfncduQ713aKI7VMhCedJWP";
              System.out.println(JwtUtil.analyzeToken(token)); // 12345678
          }
      
          @Test
          public void verifyTokenTest(){
              String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpc3MiOiJkdXN0IiwiVVNFUl9JRCI6MTIzNDU2Nzh9.qUNgiHKB5uIWhhpf8GM6hdcaE9hTvDJG9UmmMpcCPpfncduQ713aKI7VMhCedJWP";
              System.out.println(JwtUtil.verifyToken(token)); // true
          }
      }
      
      

    golang版本

    • 导入包

      go get -u github.com/dgrijalva/jwt-
      
    • JWTUtil.go

      package testcase
      
      import (
      	"errors"
      	"log"
      	"time"
      	"github.com/dgrijalva/jwt-go"
      )
      
      type JWT struct {
      	SigningKey []byte
      }
      var (
      	TokenExpired error = errors.New("Token is expired")
      	TokenNotValidYet error = errors.New("Token not active yet")
      	TokenMalformed error = errors.New("That's not even a token")
      	TokenInvalid error = errors.New("Couldn't handle this token:")
      	SignKey string = "dust"
      )
      type CustomClaims struct {
      	ID int64 `json:"id"`
      	jwt.StandardClaims
      }
      func NewJWT() *JWT {
      	return &JWT{
      		[]byte(GetSignKey()),
      	}
      }
      func GetSignKey() string {
      	return SignKey
      }
      func SetSignKey(key string) string {
      	SignKey = key
      	return SignKey
      }
      func (j *JWT) CreateToken(claims CustomClaims) (string, error) {
      	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
      	return token.SignedString(j.SigningKey)
      }
      func (j *JWT) ParseToken(tokenString string) (*CustomClaims, error) {
      	token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
      		return j.SigningKey, nil
      	})
      	if err != nil {
      		if ve, ok := err.(*jwt.ValidationError); ok {
      			if ve.Errors&jwt.ValidationErrorMalformed != 0 {
      				return nil, TokenMalformed
      			} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
      				// Token is expired
      				return nil, TokenExpired
      			} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
      				return nil, TokenNotValidYet
      			} else {
      				return nil, TokenInvalid
      			}
      		}
      	}
      	if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
      		return claims, nil
      	}
      	return nil, TokenInvalid
      }
      
      func (j *JWT) RefreshToken(tokenString string) (string, error) {
      	jwt.TimeFunc = func() time.Time {
      		return time.Unix(0, 0)
      	}
      	token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
      		return j.SigningKey, nil
      	})
      	if err != nil {
      		return "", err
      	}
      	if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
      		jwt.TimeFunc = time.Now
      		claims.StandardClaims.ExpiresAt = time.Now().Add(1 * time.Hour).Unix()
      		return j.CreateToken(*claims)
      	}
      	return "", TokenInvalid
      }
      
      // 生成令牌
      func GenerateToken(id int64) (token string, err error) {
      	j := NewJWT()
      	claims := CustomClaims{
      		id,
      		jwt.StandardClaims{
      			//NotBefore: int64(time.Now().Unix() - 1000), // 签名生效时间
      			ExpiresAt: int64(time.Now().Unix() + 1*60), // 过期时间 一小时
      			Issuer:    "dust",                          //签名的发行者
      		},
      	}
      
      	if token, err = j.CreateToken(claims); err != nil {
      		log.Printf(	"j.CreateToken(claims) err:%s", err.Error())
      		return
      	}
      
      	return token, nil
      }
      
    • 测试JWTUtil_test.go

      package testcase
      
      import (
      	"testing"
      	"time"
      )
      
      func TestGenerateToken(t *testing.T) {
      	var (
      		token string
      		err   error
      	)
      
      	if token, err = GenerateToken(123456); err != nil {
      		t.Fatalf("GenerateToken错误,错误信息:%s", err.Error())
      	}
      	t.Logf("token 值:%s", token)
      }
      
      func TestParseToken(t *testing.T) {
      	var (
      		err    error
      		claims *CustomClaims
      	)
      	token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MjM0NTY3LCJleHAiOjE1NjI4MTAyNTIsImlzcyI6ImR1c3QifQ.OxY2F0mOX8Y8XhMPHcgxmXENyHAwg_i9eCWqokIw0QE"
      	jwt := NewJWT()
      	if claims, err = jwt.ParseToken(token); err != nil {
      		t.Fatalf("ParseToken错误,错误信息:%s", err.Error())
      	}
      	t.Logf("claims中ID 值:%d", claims.ID)
      }
      
      func TestRefreshToken(t *testing.T) {
      	var (
      		err    error
      		newToken string
      	)
      	//token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MTIzNDU2LCJleHAiOjE1NjI3NTA3NzcsImlzcyI6ImR1c3QiLCJuYmYiOjE1NjI3NDk3MTd9.W-qTms5UeuBRtF6VfksaZeZANZWfP5NdFHwYPGDMp98"
      	jwt := NewJWT()
      	createToken, _ := GenerateToken(234567)
      	time.Sleep(62 * time.Second)
      	if _, err = jwt.ParseToken(createToken); err != nil && err == TokenExpired {
      		if newToken,err = jwt.RefreshToken(createToken); err == nil {
      			t.Logf("newToken 值:%s", newToken)
      		} else {
      			t.Fatalf("RefreshToken错误,错误信息:%s", err.Error())
      		}
      	}
      }
      
  • 相关阅读:
    getline在windows系统下的怪现象
    android camera根据屏幕图像大小设置显示
    android camera以时间来命名照片文件
    android 基本的画图方法
    android 开发使用剪切板传递数据
    用keytool生成一个自签名证书,并导出到文件
    VBA,两个sheet根据第一列id相同比较其余列,不同的值放到sheet3中
    摄像头视频采集压缩及传输
    Extjs 3根据数据库动态生成checkboxgroup(extjs系列1)
    Extjs 3,jstl根据数据库数据自动构建FormPanel(Extjs系列2)
  • 原文地址:https://www.cnblogs.com/dust90/p/11168585.html
Copyright © 2011-2022 走看看