go+JWT运用

JWT简介

JWT简介
生成RSA密钥地址

生成token

jwt.go

package token

import (
	"crypto/rsa"
	"github.com/dgrijalva/jwt-go"
	"time"
)

type JWTTokenGen struct {
	privateKey *rsa.PrivateKey
	Issue      string
	nowFunc    func() time.Time
}

func NewJWTTokenGen(issuer string, privateKey *rsa.PrivateKey) *JWTTokenGen {
	return &JWTTokenGen{
		Issue:      issuer,
		nowFunc:    time.Now,
		privateKey: privateKey,
	}
}

// GenerateToken 生成token
func (t JWTTokenGen) GenerateToken(accountId string, expire time.Duration) (string, error) {
	nowSec := t.nowFunc().Unix()
	token := jwt.NewWithClaims(jwt.SigningMethodRS512, jwt.StandardClaims{
		Issuer:    t.Issue,
		IssuedAt:  nowSec,
		ExpiresAt: nowSec + int64(expire.Seconds()),
		Subject:   accountId,
	})
	return token.SignedString(t.privateKey)
}

jwt_test.go

package token

import (
	"github.com/dgrijalva/jwt-go"
	"testing"
	"time"
)

const PRIVATE_KEY = `-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAhNgHkR11LVmPitKIDVku3X+gBs8Cv2bbo4NKjIgOSIIF2QMB
F26Z1pXSIDaOupq321XJZ7tkbmOYjY3As2kquyhzOpPnSQzz24Vz7/QpAi7+oWZj
RWlZqWynRUm3Ui10RK59IWpSSKsRzl+BC3yc/PHteiO5GKwLfqLqxauatCQHfiZK
5rnmf5lSmh2vO8jY8rrmOK2lQxyMBgSR4V3XGU7Ylq4DLs/jBDA0yizLr8PqhGQo
NUx6U3GVkBXvyaoNb3VRFIRtAYf1qZo5yDsF3R4cQ0sQDQ1RGegAepgBMyjdw3AR
HQDJHcdjODU2pcTa+GVJQpm0UTTL3b1rcXXZbwIDAQABAoIBAAS5EXvNSk80cfAD
kCa5Vvs1AGF9lqFrbL+heVMJu0hEpySSAMXufrWsWe4fQm/L9GFt6V0wwl9SVygh
NAqs4IIK7B3XCFAGj9zsH7UWPyb+uLrQQxNCrZdib4f9GPFpAEs40OYRO5+txVJK
/vGDmqk7iK/g+UGxTC9SZ3pjoXpqB+X4nwAlfpPFeHcxHz0PSIYoii4/U0VL02Pf
TrYkRdHYLx77lmezF/GfgpMPu+1iHAfdlKZJyQdl+G3ZLJIsLiLdtKdfMHXsUses
maiuy2WrCk4GFWHL0LXXu6bDEuz0nCTM+1mQQ5hqLLLFpBmghq8XtxiXAvMFDepU
/dTljuECgYEA8qyHoM3qt6P8BqiP9Vxz8cZ+qqwV0iDtvuBV/MngC5g07aZOJ8EJ
1Ow+l0b4FXEUdWShZ49SJyIHb3znkVbKD9+w/daqf2sKqlMsRSaidgc7pVQClC2j
mGUiSBgN3yWMYzOX/ylpnl1cozCtZl8yqM6M0rc5+GG9MN/+8YEr+fcCgYEAjCOG
01L8lxiyleyLeznO5+SzvDtXtn+sMuvQI4ughLv954O+aeZ3pWrYwz7VA+kzlk7U
Djta3fCzV4lyOSoOwv7BFO+j48wFPNW6f86X5NMzHPFwGlH8rHAp+nkX5rgutNvA
UkayEWgbFL76bF+NjBR8lwhlRz+sPasFb2c8fkkCgYBp8EudNYeb96iUN43w7RVo
nOC7HTjBbMKdK04edvqp1R52CL3huPHT0/ZXEBJJOf5WaUHU9cpFbyOT1hE5b4vy
dhLMHaR8z3vuczTGU2Fk6S9us0gU6/+ZDb1zf5y+p6OrwuA98hQ7oEJKs3tfT3vM
Ga98ZaSW/AQdjAu93kgWbQKBgDpvlgkI0csvwUhDGuaHdH++HjSfijPPiT6yllg8
IPM4cOfZR81hDQMtSrYfvTOkSp6iwEou9fUWKbKW3cp4fy9Qi7LvOqgCqyxy8xHY
U/5XEzk+dECFb5d4LgkD9bN/mfpQqCGm2RnpD2HXQRVvwtZmtI1GMvVC18/fQKTz
p4YBAoGAe5bPW1M5ErADjkPmvxYds1ouZAt9VxoUd9dACjb7AXAwrQnOPpu1clYb
1Vr1fgBmm/Iux5lQNOXbmrZt27TI4IzQn7y+ZOFWMFHQDBZWEvj9QW1V0fx9Mmm7
1WgOvPFJgLliXz3tcRK0EQlaCknrE9UI8z4HTe0xkYYIfPwBb88=
-----END RSA PRIVATE KEY-----
`

func TestJWTTokenGen_GenerateToken(t *testing.T) {
	key, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(PRIVATE_KEY))
	if err != nil {
		t.Fatalf("cannot parse private key: %v", err)
	}
	g := NewJWTTokenGen("coolcar/auth", key)
	g.nowFunc = func() time.Time {
		return time.Unix(1648371523,0)
	}
	token, err := g.GenerateToken("1234567890", 2*time.Hour)
	if err != nil {
		t.Errorf("cannot generate token:%v",err)
	}
	want := "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDgzNzg3MjMsImlhdCI6MTY0ODM3MTUyMywiaXNzIjoiY29vbGNhci9hdXRoIiwic3ViIjoiMTIzNDU2Nzg5MCJ9.ZSWm3AjbEQ6aTAqMw-qhus-7oyBZXY-tnqjsdZM7t7wke3yMuGyp4qNJCIQcUnmnHH0OA1QOuv5Sa9_aZJRibtSyhlV9WbTE7sx65fuf3bYM3ErjIFV1qR_qw5jXaP73uEQdIXceoUyuNsWWErbq_QBlF7rVSS76cvxAEMq_JSnAgK7Z7llm9fF5c375DUnWFA2nRJnrbex40Xh4eKErtBLvF8bFYVgXwPPoqviy8jUVwjTR33VRdIYWH3JE8IDgz_gZk8bRXrxeMwU2_E9fvYFP_sbgHOTrAZIR7rgw23wucsUMOb-1wopEv2npIq6aGU9XGcovdkcVQFxq_iUgMg"
	if token != want {
		t.Errorf("wrong token generated. want: %q;\n got:%q",want,token)
	}
}

在这里插入图片描述

验证token

token.go

package token

import (
	"crypto/rsa"
	"fmt"
	"github.com/dgrijalva/jwt-go"
)

type JWTTokenVerifier struct {
	PublicKey *rsa.PublicKey
}

// Verify 验证token得到PAYLOAD中的sub
func (v *JWTTokenVerifier) Verify(token string) (string, error) {

	t, err := jwt.ParseWithClaims(token, &jwt.StandardClaims{}, func(token *jwt.Token) (interface{}, error) {
		return v.PublicKey, nil
	})
	if err != nil {
		return "", fmt.Errorf("cannot parse token: %v", err)
	}
	if !t.Valid {
		return "", fmt.Errorf("token not valid")
	}
	clm, ok := t.Claims.(*jwt.StandardClaims)
	if !ok {
		return "", fmt.Errorf("token claim is not StandardClaims")
	}
	if err := clm.Valid(); err != nil {
		return "", fmt.Errorf("claim not valid: %v", err)
	}
	return clm.Subject, nil

}

token_test.go

package token

import (
	"github.com/dgrijalva/jwt-go"
	"testing"
)

const PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhNgHkR11LVmPitKIDVku
3X+gBs8Cv2bbo4NKjIgOSIIF2QMBF26Z1pXSIDaOupq321XJZ7tkbmOYjY3As2kq
uyhzOpPnSQzz24Vz7/QpAi7+oWZjRWlZqWynRUm3Ui10RK59IWpSSKsRzl+BC3yc
/PHteiO5GKwLfqLqxauatCQHfiZK5rnmf5lSmh2vO8jY8rrmOK2lQxyMBgSR4V3X
GU7Ylq4DLs/jBDA0yizLr8PqhGQoNUx6U3GVkBXvyaoNb3VRFIRtAYf1qZo5yDsF
3R4cQ0sQDQ1RGegAepgBMyjdw3ARHQDJHcdjODU2pcTa+GVJQpm0UTTL3b1rcXXZ
bwIDAQAB
-----END PUBLIC KEY-----
`

func TestJWTTokenVerifer_Verify(t *testing.T) {
	pubKey, err := jwt.ParseRSAPublicKeyFromPEM([]byte(PUBLIC_KEY))
	if err != nil {
		t.Fatalf("cannot  parse public key: %v", err)
	}
	v := &JWTTokenVerifier{
		PublicKey: pubKey,
	}
	token := "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2NDgzNzg3MjMsImlhdCI6MTY0ODM3MTUyMywiaXNzIjoiY29vbGNhci9hdXRoIiwic3ViIjoiMTIzNDU2Nzg5MCJ9.ZSWm3AjbEQ6aTAqMw-qhus-7oyBZXY-tnqjsdZM7t7wke3yMuGyp4qNJCIQcUnmnHH0OA1QOuv5Sa9_aZJRibtSyhlV9WbTE7sx65fuf3bYM3ErjIFV1qR_qw5jXaP73uEQdIXceoUyuNsWWErbq_QBlF7rVSS76cvxAEMq_JSnAgK7Z7llm9fF5c375DUnWFA2nRJnrbex40Xh4eKErtBLvF8bFYVgXwPPoqviy8jUVwjTR33VRdIYWH3JE8IDgz_gZk8bRXrxeMwU2_E9fvYFP_sbgHOTrAZIR7rgw23wucsUMOb-1wopEv2npIq6aGU9XGcovdkcVQFxq_iUgMg"
	accountID, err := v.Verify(token)
	if err != nil {
		t.Errorf("verification failed: %v", err)
	}
	want := "1234567890"
	if accountID != want {
		t.Errorf("wrong account id. wangt:%q, got:%q", want, accountID)
	}
}

在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.番茄炒蛋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值