代码示例:
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"errors"
"fmt"
"github.com/dgrijalva/jwt-go"
"time"
)
var privateKey *ecdsa.PrivateKey
type Claims struct {
UserId uint
jwt.StandardClaims
}
func main() {
var err error
privateKey, _, err= getEcdsaKey(2) //生成椭圆曲线的私钥
if err!=nil {
fmt.Println("getEcdsaKey is error!",err)
return
}
token, err := ReleaseToken(privateKey)
if err!=nil {
fmt.Println("生成token错误:",err)
return
}
fmt.Println("生成的token为:",token)
parseToken, claims, err := ParseToken(token,privateKey)
//fmt.Println(privateKey)
fmt.Println(parseToken,claims,err)
userId := claims.UserId
if userId!=001 { //001为数据库中的数据,表示分发给某一用户的Id
fmt.Println("权限不足!")
return
}
fmt.Println("验证通过!")
}
//生成token
func ReleaseToken(key *ecdsa.PrivateKey) (string,error) {
expirationTime := time.Now().Add(7 * 24 * time.Hour) //截止时间:从当前时刻算起,7天
claims := &Claims{
UserId: 001, //分发给某一用户的token,模拟数据为 001
StandardClaims: jwt.StandardClaims{
ExpiresAt: expirationTime.Unix(), //过期时间
IssuedAt: time.Now().Unix(), //发布时间
Issuer: "jiangzhou", //发布者
Subject: "user token", //主题
},
}
token := jwt.NewWithClaims(jwt.SigningMethodES256, claims) //生成token
tokenString, err := token.SignedString(key) //签名
if err!=nil {
fmt.Println("生成token错误:",err)
return "", err
}
//fmt.Println("token:",tokenString)
return tokenString,err
}
//解析token
func ParseToken(tokenString string,key *ecdsa.PrivateKey) (*jwt.Token, *Claims, error){
claims := &Claims{}
token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (i interface{}, err error) {
token.Method=jwt.SigningMethodES256
return key, nil
})
return token, claims, err
}
func getEcdsaKey(length int) (*ecdsa.PrivateKey, ecdsa.PublicKey, error){
var err error
var prk *ecdsa.PrivateKey
var puk ecdsa.PublicKey
var curve elliptic.Curve
switch length {
case 1:
curve = elliptic.P224()
case 2:
curve = elliptic.P256()
case 3:
curve = elliptic.P384()
case 4:
curve = elliptic.P521()
default:
err =errors.New("输入的签名等级错误!")
}
prk, err = ecdsa.GenerateKey(curve,rand.Reader) //通过 "crypto/rand" 模块产生的随机数生成私钥
if err != nil {
return prk, puk, err
}
puk = prk.PublicKey
return prk, puk, err
}
运行效果: