添加支持refreshtoken的实现

This commit is contained in:
Yavolte 2025-07-23 09:35:46 +08:00
parent 13010ec1a4
commit 0de20d5ddf
1 changed files with 40 additions and 28 deletions

View File

@ -27,6 +27,7 @@ type (
tokenStore TokenStore tokenStore TokenStore
turnstileValidateUrl string turnstileValidateUrl string
turnstileSiteKey string turnstileSiteKey string
enableRefreshToken bool
} }
turnstileRequest struct { turnstileRequest struct {
@ -65,6 +66,12 @@ func WithAuthCache(cache cache.Cache) AuthOption {
} }
} }
func WithRefreshToken() AuthOption {
return func(o *authOptions) {
o.enableRefreshToken = true
}
}
func WithTokenStore(store TokenStore) AuthOption { func WithTokenStore(store TokenStore) AuthOption {
return func(o *authOptions) { return func(o *authOptions) {
o.tokenStore = store o.tokenStore = store
@ -152,6 +159,15 @@ func (s *AuthService) Login(ctx context.Context, req *pb.LoginRequest) (res *pb.
IssuedAt: time.Now().Unix(), IssuedAt: time.Now().Unix(),
ExpirationAt: time.Now().Add(time.Second * time.Duration(s.opts.ttl)).Unix(), ExpirationAt: time.Now().Add(time.Second * time.Duration(s.opts.ttl)).Unix(),
} }
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
res = &pb.LoginResponse{}
if res.Token, err = token.SignedString(s.opts.secret); err == nil {
res.Uid = model.Uid
res.Username = model.Username
res.Expires = s.opts.ttl
}
if s.opts.enableRefreshToken {
refreshClaims := types.Claims{ refreshClaims := types.Claims{
Uid: model.Uid, Uid: model.Uid,
Role: model.Role, Role: model.Role,
@ -159,16 +175,9 @@ func (s *AuthService) Login(ctx context.Context, req *pb.LoginRequest) (res *pb.
IssuedAt: time.Now().Unix(), IssuedAt: time.Now().Unix(),
ExpirationAt: time.Now().Add(time.Hour * 48).Unix(), ExpirationAt: time.Now().Add(time.Hour * 48).Unix(),
} }
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
refreshToken := jwt.NewWithClaims(jwt.SigningMethodHS256, refreshClaims) refreshToken := jwt.NewWithClaims(jwt.SigningMethodHS256, refreshClaims)
res = &pb.LoginResponse{}
if res.Token, err = token.SignedString(s.opts.secret); err == nil {
res.Uid = model.Uid
res.Username = model.Username
res.Expires = s.opts.ttl
}
res.RefreshToken, err = refreshToken.SignedString(s.opts.secret) res.RefreshToken, err = refreshToken.SignedString(s.opts.secret)
}
loginModel := &models.Login{} loginModel := &models.Login{}
loginModel.Uid = model.Uid loginModel.Uid = model.Uid
loginModel.AccessToken = res.Token loginModel.AccessToken = res.Token
@ -197,30 +206,33 @@ func (s *AuthService) Logout(ctx context.Context, req *pb.LogoutRequest) (res *p
func (s *AuthService) RefreshToken(ctx context.Context, req *pb.RefreshTokenRequest) (res *pb.RefreshTokenResponse, err error) { func (s *AuthService) RefreshToken(ctx context.Context, req *pb.RefreshTokenRequest) (res *pb.RefreshTokenResponse, err error) {
var ( var (
token *jwt.Token refreshToken *jwt.Token
) )
if token, err = jwt.ParseWithClaims(req.RefreshToken, &types.Claims{}, func(token *jwt.Token) (interface{}, error) { if !s.opts.enableRefreshToken {
err = errors.ErrAccessDenied
return
}
if refreshToken, err = jwt.ParseWithClaims(req.RefreshToken, &types.Claims{}, func(token *jwt.Token) (interface{}, error) {
return s.opts.secret, nil return s.opts.secret, nil
}); err != nil { }); err != nil {
return return
} }
if claims, ok := token.Claims.(*types.Claims); ok { refreshClaims, ok := refreshToken.Claims.(*types.Claims)
if !ok {
err = errors.ErrIncompatible
}
tokenClaims := types.Claims{ tokenClaims := types.Claims{
Uid: claims.Uid, Uid: refreshClaims.Uid,
Role: claims.Role, Role: refreshClaims.Role,
Admin: claims.Admin, Admin: refreshClaims.Admin,
IssuedAt: time.Now().Unix(), IssuedAt: time.Now().Unix(),
ExpirationAt: time.Now().Add(time.Second * time.Duration(s.opts.ttl)).Unix(), ExpirationAt: time.Now().Add(time.Second * time.Duration(s.opts.ttl)).Unix(),
} }
token := jwt.NewWithClaims(jwt.SigningMethodHS256, tokenClaims) token := jwt.NewWithClaims(jwt.SigningMethodHS256, tokenClaims)
res = &pb.RefreshTokenResponse{} res = &pb.RefreshTokenResponse{}
if res.Token, err = token.SignedString(s.opts.secret); err == nil { if res.Token, err = token.SignedString(s.opts.secret); err == nil {
res.Uid = claims.Uid res.Uid = refreshClaims.Uid
res.Expires = s.opts.ttl res.Expires = s.opts.ttl
return
}
} else {
err = errors.ErrIncompatible
} }
return return
} }