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,
}
}
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)
}
}
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/3da5dbaf289f95dc0ddca7e1bf9b3050.png)
验证token
token.go
package token
import (
"crypto/rsa"
"fmt"
"github.com/dgrijalva/jwt-go"
)
type JWTTokenVerifier struct {
PublicKey *rsa.PublicKey
}
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)
}
}
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/4e40d1cbb73726f6f796bcd85f03b6b1.png)