|
// generateToken returns a JWT token string. Please see the URL for details:
// http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-13#section-4.1
func generateToken(aud, username, issuer, privateKey string) (string, error) {
tokenCacheMu.Lock()
defer tokenCacheMu.Unlock()
uniqKey := aud + username + issuer // neglect privateKey, its always the same
signed, ok := tokenCache[uniqKey]
if ok {
return signed, nil
}
tknID, err := uuid.NewV4()
if err != nil {
return "", errors.New("Server error: Cannot generate a token")
}
//>
// for processing.
ttl := TokenTTL
// Implementers MAY provide for some small leeway, usually no more than
// a few minutes, to account for clock skew.
leeway := TokenLeeway
tkn := jwt.New(jwt.GetSigningMethod("RS256"))
tkn.Claims["iss"] = issuer // Issuer
tkn.Claims["sub"] = username // Subject
tkn.Claims["aud"] = aud // Audience
tkn.Claims["exp"] = time.Now().UTC().Add(ttl).Add(leeway).Unix() // Expiration Time
tkn.Claims["nbf"] = time.Now().UTC().Add(-leeway).Unix() // Not Before
tkn.Claims["iat"] = time.Now().UTC().Unix() // Issued At
tkn.Claims["jti"] = tknID.String() // JWT>
signed, err = tkn.SignedString([]byte(privateKey))
if err != nil {
return "", errors.New("Server error: Cannot generate a token")
}
// cache our token
tokenCache[uniqKey] = signed
// cache invalidation, because we cache the token in tokenCache we need to
// invalidate it expiration time. This was handled usually within JWT, but
// now we have to do it manually for our own cache.
time.AfterFunc(TokenTTL-TokenLeeway, func() {
tokenCacheMu.Lock()
defer tokenCacheMu.Unlock()
delete(tokenCache, uniqKey)
})
return signed, nil
}
|
|
|