gofiber-study/services/auth/auth.go

118 lines
2.5 KiB
Go
Raw Normal View History

package auth
import (
"context"
"errors"
"github.com/goccy/go-json"
"gofiber.study.skcks.cn/common/logger"
"gofiber.study.skcks.cn/common/utils"
"gofiber.study.skcks.cn/global"
2022-10-06 20:46:17 +08:00
"gofiber.study.skcks.cn/model/dto"
"gofiber.study.skcks.cn/model/generic/models"
"gofiber.study.skcks.cn/model/vo"
"time"
)
var (
Failed = errors.New("账号或密码错误")
InvalidRefreshToken = errors.New("刷新令牌已失效")
)
const (
Separator = ":"
RefreshTokenPrefix = "RefreshToken" + Separator
)
type Service struct {
}
var Services *Service
func InitService() {
Services = &Service{}
}
2022-10-06 22:22:54 +08:00
// generateAndSaveRefreshToken
//
// 生成并保存 refreshToken 刷新令牌
func (s *Service) generateAndSaveRefreshToken(user *models.User) (refreshToken string, err error) {
refreshToken, err = global.GetNanoId()
if err != nil {
return
}
expire := time.Duration(global.Config.Jwt.Expire*2) * time.Second
ctx := context.Background()
global.Redis.Set(ctx, RefreshTokenPrefix+refreshToken, utils.Json(user), expire)
return
}
func (s *Service) Login(login *dto.Login) (result *vo.Login, err error) {
user := &models.User{Account: login.Account, Password: login.Password}
exist, err := global.DataSources.Get(user)
if err != nil {
return
}
if !exist {
return nil, Failed
}
token, err := global.GetToken(global.UserClaims{
Id: user.Id,
Account: user.Account,
})
if err != nil {
return
}
refreshToken, err := s.generateAndSaveRefreshToken(user)
return &vo.Login{
Token: token,
RefreshToken: refreshToken,
}, err
}
func (s *Service) RefreshToken(refreshToken string) (result *vo.Login, err error) {
2022-10-06 22:22:54 +08:00
refreshToken = RefreshTokenPrefix + refreshToken
ctx := context.Background()
2022-10-06 22:22:54 +08:00
data, err := global.Redis.Get(ctx, refreshToken).Result()
if err != nil {
return nil, InvalidRefreshToken
}
2022-10-06 22:22:54 +08:00
global.Redis.Del(ctx, refreshToken)
cache := &models.User{}
err = json.Unmarshal([]byte(data), cache)
if err != nil {
return nil, InvalidRefreshToken
}
user := &models.User{Id: cache.Id, Account: cache.Account}
exist, err := global.DataSources.Get(user)
if !exist {
2022-10-06 22:22:54 +08:00
logger.Log.Infof("未能从 %s 找到用户信息", refreshToken)
return nil, InvalidRefreshToken
}
token, err := global.GetToken(global.UserClaims{
Id: user.Id,
Account: user.Account,
})
if err != nil {
return
}
refreshToken, err = s.generateAndSaveRefreshToken(user)
return &vo.Login{
Token: token,
RefreshToken: refreshToken,
}, err
}