mirror of https://github.com/gogs/gogs.git
103 lines
2.2 KiB
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")
|
|
}
|