在 Go 語言中使用 Jwt Token 贤牛,我們采用更加安全的RAS256方式進(jìn)行簽名尘吗。使用私鑰進(jìn)行簽發(fā) Token忘古,使用公鑰進(jìn)行簽名驗(yàn)證苍息。
生成密鑰對(duì)
在項(xiàng)目根目錄下面創(chuàng)建 Makefile
文件源譬,填充下面的內(nèi)容:
.PHONY: cert-private cert-public
cert-private:
@openssl genrsa -out cert/id_rsa 4096
cert-public:
@openssl rsa -in cert/id_rsa -pubout -out cert/id_rsa_2.pub
在 Shell 中執(zhí)行:
make cert-private && make cert-public
來生成對(duì)應(yīng)的私鑰和公鑰
使用下面的代碼來創(chuàng)建main.go
文件:
package main
import (
"bytes"
"fmt"
"log"
"os"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
)
var (
privateKey *bytes.Buffer
publicKey *bytes.Buffer
)
func generateToken() (string, error) {
key, err := jwt.ParseRSAPrivateKeyFromPEM(privateKey.Bytes())
if err != nil {
return "", err
}
now := time.Now().UTC()
claims := jwt.RegisteredClaims{
IssuedAt: jwt.NewNumericDate(now),
ID: uuid.NewString(),
ExpiresAt: jwt.NewNumericDate(now.Add(10 * time.Minute)),
}
token, err := jwt.NewWithClaims(jwt.SigningMethodRS256, claims).SignedString(key)
if err != nil {
return "", err
}
return token, nil
}
func validate(token string) (map[string]interface{}, error) {
key, err := jwt.ParseRSAPublicKeyFromPEM(publicKey.Bytes())
if err != nil {
return nil, err
}
parsed, err := jwt.Parse(token, func(jwtToken *jwt.Token) (interface{}, error) {
if _, ok := jwtToken.Method.(*jwt.SigningMethodRSA); !ok {
return nil, fmt.Errorf("unexpected method:%s", jwtToken.Header["alg"])
}
return key, nil
})
if err != nil {
return nil, err
}
claims, ok := parsed.Claims.(jwt.MapClaims)
if !ok || !parsed.Valid {
return nil, fmt.Errorf("invalid token:%w", err)
}
return claims, nil
}
func main() {
prKey, err := os.ReadFile("cert/id_rsa")
if err != nil {
log.Fatal(err)
}
privateKey = bytes.NewBuffer(prKey)
pubKey, err := os.ReadFile("cert/id_rsa.pub")
if err != nil {
log.Fatal(err)
}
publicKey = bytes.NewBuffer(pubKey)
token, err := generateToken()
if err != nil {
log.Fatal(err)
}
log.Printf("token:%s", token)
m, err := validate(token)
if err != nil {
log.Fatal(err)
}
log.Printf("token claims:%v", m)
}
編譯執(zhí)行:
go run main.go
生成的 Token 可以在jwt.io網(wǎng)站上進(jìn)行查看集惋,使用公鑰進(jìn)行簽名校驗(yàn),如圖:
image.png