package token
import (
"crypto/rsa"
"time"
"github.com/dgrijalva/jwt-go"
)
// JWTTokenGen generates a JWT token.
type JWTTokenGen struct {
privateKey *rsa.PrivateKey
issuer string
nowFunc func() time.Time
}
// NewJWTTokenGen new JWT token
func NewJWTTokenGen(issuer string, privateKey *rsa.PrivateKey) *JWTTokenGen {
return &JWTTokenGen{
privateKey: privateKey,
issuer: issuer,
nowFunc: time.Now,
}
}
// GenerateToken generates a token.
func (t *JWTTokenGen) GenerateToken(accountID string, expire time.Duration) (string, error) {
nowSec := t.nowFunc().Unix()
tkn := jwt.NewWithClaims(jwt.SigningMethodRS512, jwt.StandardClaims{
Issuer: t.issuer,
IssuedAt: nowSec,
ExpiresAt: nowSec + int64(expire.Seconds()),
Subject: accountID,
})
return tkn.SignedString(t.privateKey)
}
测试:
package token
import (
"testing"
"time"
"github.com/dgrijalva/jwt-go"
)
const privateKey = `-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAnzyis1ZjfNB0bBgKFMSvvkTtwlvBsaJq7S5wA+kzeVOVpVWw
kWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHcaT92whREFpLv9cj5lTeJSibyr/Mr
m/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIytvHWTxZYEcXLgAXFuUuaS3uF9gEi
NQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0e+lf4s4OxQawWD79J9/5d3Ry0vbV
3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWbV6L11BWkpzGXSW4Hv43qa+GSYOD2
QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9MwIDAQABAoIBACiARq2wkltjtcjs
kFvZ7w1JAORHbEufEO1Eu27zOIlqbgyAcAl7q+/1bip4Z/x1IVES84/yTaM8p0go
amMhvgry/mS8vNi1BN2SAZEnb/7xSxbflb70bX9RHLJqKnp5GZe2jexw+wyXlwaM
+bclUCrh9e1ltH7IvUrRrQnFJfh+is1fRon9Co9Li0GwoN0x0byrrngU8Ak3Y6D9
D8GjQA4Elm94ST3izJv8iCOLSDBmzsPsXfcCUZfmTfZ5DbUDMbMxRnSo3nQeoKGC
0Lj9FkWcfmLcpGlSXTO+Ww1L7EGq+PT3NtRae1FZPwjddQ1/4V905kyQFLamAA5Y
lSpE2wkCgYEAy1OPLQcZt4NQnQzPz2SBJqQN2P5u3vXl+zNVKP8w4eBv0vWuJJF+
hkGNnSxXQrTkvDOIUddSKOzHHgSg4nY6K02ecyT0PPm/UZvtRpWrnBjcEVtHEJNp
bU9pLD5iZ0J9sbzPU/LxPmuAP2Bs8JmTn6aFRspFrP7W0s1Nmk2jsm0CgYEAyH0X
+jpoqxj4efZfkUrg5GbSEhf+dZglf0tTOA5bVg8IYwtmNk/pniLG/zI7c+GlTc9B
BwfMr59EzBq/eFMI7+LgXaVUsM/sS4Ry+yeK6SJx/otIMWtDfqxsLD8CPMCRvecC
2Pip4uSgrl0MOebl9XKp57GoaUWRWRHqwV4Y6h8CgYAZhI4mh4qZtnhKjY4TKDjx
QYufXSdLAi9v3FxmvchDwOgn4L+PRVdMwDNms2bsL0m5uPn104EzM6w1vzz1zwKz
5pTpPI0OjgWN13Tq8+PKvm/4Ga2MjgOgPWQkslulO/oMcXbPwWC3hcRdr9tcQtn9
Imf9n2spL/6EDFId+Hp/7QKBgAqlWdiXsWckdE1Fn91/NGHsc8syKvjjk1onDcw0
NvVi5vcba9oGdElJX3e9mxqUKMrw7msJJv1MX8LWyMQC5L6YNYHDfbPF1q5L4i8j
8mRex97UVokJQRRA452V2vCO6S5ETgpnad36de3MUxHgCOX3qL382Qx9/THVmbma
3YfRAoGAUxL/Eu5yvMK8SAt/dJK6FedngcM3JEFNplmtLYVLWhkIlNRGDwkg3I5K
y18Ae9n7dHVueyslrb6weq7dTkYDi3iOYRW8HRkIQh06wEdbxt0shTzAJvvCQfrB
jg/3747WSsf/zBTcHihTRBdAv6OmdhV4/dD5YBfLAkLrd+mX7iE=
-----END RSA PRIVATE KEY-----`
func TestGenerateToken(t *testing.T) {
key, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(privateKey))
if err != nil {
t.Fatalf("cannot parse private key: %v", err)
}
g := NewJWTTokenGen("coolcar/auth", key)
g.nowFunc = func() time.Time {
return time.Unix(1516239022, 0)
}
tkn, err := g.GenerateToken("609a94ab26d5a7fa0220b46e", 2*time.Hour)
if err != nil {
t.Errorf("cannot generate token: %v", err)
}
want := "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTYyNDYyMjIsImlhdCI6MTUxNjIzOTAyMiwiaXNzIjoiY29vbGNhci9hdXRoIiwic3ViIjoiNjA5YTk0YWIyNmQ1YTdmYTAyMjBiNDZlIn0.IEo7jhIx22VkldgRmoBgYw09srCz1dYyilITuqWhVIK9kpOSnjA1-ESl2PDRD-quvgqrWVLB2YLvuhBhkx0sPflg5heepq3scul0zjkD3ewE7OR8va_byHf4ha0mw3P-PVtYpFvJ-aaAd9DAVKonG_EwS-12TnnSgcj7vB1w8z6yDXZa1rSEImzsh4shApTBRx2MFR1mZxZQntd7T5_bqVN4xbs3P61OBYZUJmWkMPmsLANb3RLwe6e3VHM0uGMknfRjiunmTg54BA2hjoZDEIie6bm1-tz5ZbrxSTmJwxtO3K_kDIdbs9NOc4hf_K2FoS3LVJmjZgG_hWK3M0PMUw"
if tkn != want {
t.Errorf("wrong token generated. want: %q; got:%q", want, tkn)
}
}