gogs/internal/tool/jwt.go

103 lines
2.2 KiB
Go

package tool
import (
"crypto/rand"
"fmt"
"github.com/dgrijalva/jwt-go"
"gogs.io/gogs/internal/conf"
"time"
)
type Subject int
const (
SubjectActiveAccount Subject = 1
SubjectActiveEmail Subject = 2
SubjectForgetPasswd Subject = 3
)
var secretKey = make([]byte, 32)
func init() {
if _, err := rand.Read(secretKey); err != nil {
panic(err)
}
}
type Claims struct {
Audience string `json:"aud,omitempty"`
ExpiresAt int64 `json:"exp,omitempty"`
Id int64 `json:"jti,omitempty"`
Email string `json:"email,omitempty"`
IssuedAt int64 `json:"iat,omitempty"`
Issuer string `json:"iss,omitempty"`
NotBefore int64 `json:"nbf,omitempty"`
Subject Subject `json:"sub,omitempty"`
}
func (c *Claims) Valid() error {
now := time.Now()
if now.After(time.Unix(c.ExpiresAt, 0)) {
return fmt.Errorf("error")
}
if now.Before(time.Unix(c.NotBefore, 0)) {
return fmt.Errorf("error")
}
if now.Before(time.Unix(c.IssuedAt, 0)) {
return fmt.Errorf("error")
}
if c.Audience != c.Email {
return fmt.Errorf("error")
}
return nil
}
func NewClaims(id int64, email string, subject Subject) *Claims {
now := time.Now()
return &Claims{
Audience: email,
ExpiresAt: now.Add(time.Duration(conf.Auth.ActivateCodeLives) * time.Minute).Unix(),
Id: id,
Email: email,
IssuedAt: now.Unix(),
Issuer: conf.Server.ExternalURL,
NotBefore: now.Unix(),
Subject: subject,
}
}
func (c *Claims) ToToken() (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
//使用指定的secret签名并获得完成的编码后的字符串token
return token.SignedString(secretKey)
}
func ParseToken(t string) (*Claims, error) {
//解析token
token, err := jwt.ParseWithClaims(t, &Claims{}, func(token *jwt.Token) (i interface{}, err error) {
return secretKey, nil
})
if err != nil {
return nil, err
}
if claims, ok := token.Claims.(*Claims); ok && claims != nil && token.Valid {
return claims, nil
} else if err := claims.Valid(); err != nil {
return nil, err
}
if claims, ok := token.Claims.(*Claims); ok && claims != nil && token.Valid {
if err := claims.Valid(); err != nil {
return nil, err
}
return claims, nil
}
return nil, fmt.Errorf("invalid token")
}