验证令牌
This commit is contained in:
parent
48f05b4e95
commit
602cd3957c
@ -1,13 +1,35 @@
|
||||
package yggdrasil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||
sutils "github.com/xmdhs/authlib-skin/service/utils"
|
||||
"github.com/xmdhs/authlib-skin/utils"
|
||||
)
|
||||
|
||||
func (y *Yggdrasil) Validate() httprouter.Handle {
|
||||
return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
|
||||
|
||||
cxt := r.Context()
|
||||
a, err := utils.DeCodeBody[yggdrasil.ValidateToken](r.Body, y.validate)
|
||||
if err != nil {
|
||||
y.logger.DebugContext(cxt, err.Error())
|
||||
handleYgError(cxt, w, yggdrasil.Error{ErrorMessage: err.Error()}, 400)
|
||||
return
|
||||
}
|
||||
err = y.yggdrasilService.ValidateToken(cxt, a)
|
||||
if err != nil {
|
||||
if errors.Is(err, sutils.ErrTokenInvalid) {
|
||||
y.logger.DebugContext(cxt, err.Error())
|
||||
handleYgError(cxt, w, yggdrasil.Error{ErrorMessage: "Invalid token.", Error: "ForbiddenOperationException"}, 403)
|
||||
return
|
||||
}
|
||||
y.logger.WarnContext(cxt, err.Error())
|
||||
handleYgError(cxt, w, yggdrasil.Error{ErrorMessage: err.Error()}, 500)
|
||||
return
|
||||
}
|
||||
w.WriteHeader(204)
|
||||
}
|
||||
}
|
||||
|
@ -34,3 +34,8 @@ type TokenUser struct {
|
||||
ID string `json:"id"`
|
||||
Properties []any `json:"properties"`
|
||||
}
|
||||
|
||||
type ValidateToken struct {
|
||||
AccessToken string `json:"accessToken" validate:"required,jwt"`
|
||||
ClientToken string `json:"clientToken"`
|
||||
}
|
||||
|
58
service/utils/auth.go
Normal file
58
service/utils/auth.go
Normal file
@ -0,0 +1,58 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/xmdhs/authlib-skin/db/ent"
|
||||
"github.com/xmdhs/authlib-skin/db/ent/usertoken"
|
||||
"github.com/xmdhs/authlib-skin/model"
|
||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrTokenInvalid = errors.New("token 无效")
|
||||
)
|
||||
|
||||
func Auth(ctx context.Context, t yggdrasil.ValidateToken, client *ent.Client, jwtKey string) error {
|
||||
token, err := jwt.ParseWithClaims(t.AccessToken, &model.TokenClaims{}, func(t *jwt.Token) (interface{}, error) {
|
||||
return []byte(jwtKey), nil
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Auth: %w", err)
|
||||
}
|
||||
|
||||
claims, ok := token.Claims.(*model.TokenClaims)
|
||||
if !ok || !token.Valid {
|
||||
return fmt.Errorf("Auth: %w", ErrTokenInvalid)
|
||||
}
|
||||
if t.ClientToken != "" && t.ClientToken != claims.CID {
|
||||
return fmt.Errorf("Auth: %w", ErrTokenInvalid)
|
||||
}
|
||||
|
||||
it, err := claims.GetIssuedAt()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Auth: %w", err)
|
||||
}
|
||||
et, err := claims.GetExpirationTime()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Auth: %w", err)
|
||||
}
|
||||
invalidTime := it.Add(et.Time.Sub(it.Time))
|
||||
if time.Now().After(invalidTime) {
|
||||
return fmt.Errorf("Auth: %w", ErrTokenInvalid)
|
||||
}
|
||||
|
||||
ut, err := client.UserToken.Query().Where(usertoken.UUIDEQ(claims.Subject)).First(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Auth: %w", err)
|
||||
}
|
||||
if strconv.FormatUint(ut.TokenID, 10) != claims.Tid {
|
||||
return fmt.Errorf("Auth: %w", ErrTokenInvalid)
|
||||
}
|
||||
return nil
|
||||
}
|
17
service/yggdrasil/validate.go
Normal file
17
service/yggdrasil/validate.go
Normal file
@ -0,0 +1,17 @@
|
||||
package yggdrasil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/xmdhs/authlib-skin/model/yggdrasil"
|
||||
"github.com/xmdhs/authlib-skin/service/utils"
|
||||
)
|
||||
|
||||
func (y *Yggdrasil) ValidateToken(ctx context.Context, t yggdrasil.ValidateToken) error {
|
||||
err := utils.Auth(ctx, t, y.client, y.config.JwtKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ValidateToken: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user