token 生产和验证
package main
import (
"crypto/rsa"
"errors"
"fmt"
"io/ioutil"
"os"
"time"
"github.com/dgrijalva/jwt-go"
)
//https://cryptotools.net/rsagen
//https://jwt.io/
type JWTToken struct {
issuer string
nowFunc func() time.Time
privateKey *rsa.PrivateKey
}
func NewJWTToken(issuer string, privateKey string) *JWTToken {
priKey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(privateKey))
if err != nil {
return nil
}
return &JWTToken{
issuer: issuer,
nowFunc: time.Now,
privateKey: priKey,
}
}
func readRSAKey(path string) string {
priKey, err := os.Open(path)
if err != nil {
panic(err)
}
priKeyBytes, err := ioutil.ReadAll(priKey)
if err != nil {
panic(err)
}
return string(priKeyBytes)
}
func (t *JWTToken) GenerateToken(accountId string, expires int) (string, error) {
tkn := jwt.NewWithClaims(jwt.SigningMethodRS512, jwt.StandardClaims{
Issuer: t.issuer,
IssuedAt: t.nowFunc().Unix(),
ExpiresAt: t.nowFunc().Unix() + int64(expires),
Subject: accountId,
})
return tkn.SignedString(t.privateKey)
}
func (t *JWTToken) tokenVerify(token string) (string, error) {
tt, err := jwt.ParseWithClaims(token, &jwt.StandardClaims{}, func(t *jwt.Token) (interface{}, error) {
pubKey := readRSAKey("Public.key")
Key, err := jwt.ParseRSAPublicKeyFromPEM([]byte(pubKey))
if err != nil {
return "", errors.New("key 失败")
}
return Key, nil
})
if err != nil {
panic(err)
}
if !tt.Valid {
panic(err)
}
clm, ok := tt.Claims.(*jwt.StandardClaims)
if !ok {
panic(err)
}
if err := clm.Valid(); err != nil {
panic(err)
}
return clm.Subject, nil
}
func main() {
priKey := readRSAKey("private.key")
jwtTokenGen := NewJWTToken("/web", priKey)
token, err := jwtTokenGen.GenerateToken("I am yaoyao.", 3600)
if err != nil {
panic(err)
}
fmt.Println(token)
con, _ := jwtTokenGen.tokenVerify(token)
fmt.Println(con)
}