2022-10-06 17:58:11 +08:00
|
|
|
package auth
|
|
|
|
|
|
|
|
import (
|
2022-10-06 22:12:43 +08:00
|
|
|
"context"
|
2022-10-06 17:58:11 +08:00
|
|
|
"errors"
|
2022-10-06 22:12:43 +08:00
|
|
|
"github.com/goccy/go-json"
|
|
|
|
"gofiber.study.skcks.cn/common/logger"
|
|
|
|
"gofiber.study.skcks.cn/common/utils"
|
2022-10-06 17:58:11 +08:00
|
|
|
"gofiber.study.skcks.cn/global"
|
2022-10-06 20:46:17 +08:00
|
|
|
"gofiber.study.skcks.cn/model/dto"
|
2022-10-06 17:58:11 +08:00
|
|
|
"gofiber.study.skcks.cn/model/generic/models"
|
2022-10-06 22:12:43 +08:00
|
|
|
"gofiber.study.skcks.cn/model/vo"
|
|
|
|
"time"
|
2022-10-06 17:58:11 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2022-10-06 23:05:31 +08:00
|
|
|
PasswordIsEmpty = errors.New("密码不能为空")
|
2022-10-06 22:12:43 +08:00
|
|
|
Failed = errors.New("账号或密码错误")
|
|
|
|
InvalidRefreshToken = errors.New("刷新令牌已失效")
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
Separator = ":"
|
|
|
|
RefreshTokenPrefix = "RefreshToken" + Separator
|
2022-10-06 17:58:11 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
type Service struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
var Services *Service
|
|
|
|
|
|
|
|
func InitService() {
|
|
|
|
Services = &Service{}
|
|
|
|
}
|
|
|
|
|
2022-10-06 22:22:54 +08:00
|
|
|
// generateAndSaveRefreshToken
|
|
|
|
//
|
|
|
|
// 生成并保存 refreshToken 刷新令牌
|
2022-10-06 22:12:43 +08:00
|
|
|
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) {
|
2022-10-06 23:05:31 +08:00
|
|
|
err = global.ValidateStruct(login)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2022-10-06 17:58:11 +08:00
|
|
|
user := &models.User{Account: login.Account, Password: login.Password}
|
|
|
|
exist, err := global.DataSources.Get(user)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if !exist {
|
2022-10-06 22:12:43 +08:00
|
|
|
return nil, Failed
|
2022-10-06 17:58:11 +08:00
|
|
|
}
|
|
|
|
|
2022-10-06 22:12:43 +08:00
|
|
|
token, err := global.GetToken(global.UserClaims{
|
2022-10-06 17:58:11 +08:00
|
|
|
Id: user.Id,
|
|
|
|
Account: user.Account,
|
|
|
|
})
|
|
|
|
|
2022-10-06 22:12:43 +08:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
refreshToken, err := s.generateAndSaveRefreshToken(user)
|
|
|
|
|
2022-10-06 23:05:31 +08:00
|
|
|
_, _ = global.DataSources.Update(user)
|
|
|
|
|
2022-10-06 22:12:43 +08:00
|
|
|
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
|
|
|
|
|
2022-10-06 22:12:43 +08:00
|
|
|
ctx := context.Background()
|
2022-10-06 22:22:54 +08:00
|
|
|
data, err := global.Redis.Get(ctx, refreshToken).Result()
|
2022-10-06 22:12:43 +08:00
|
|
|
if err != nil {
|
|
|
|
return nil, InvalidRefreshToken
|
|
|
|
}
|
|
|
|
|
2022-10-06 22:22:54 +08:00
|
|
|
global.Redis.Del(ctx, refreshToken)
|
2022-10-06 22:12:43 +08:00
|
|
|
|
|
|
|
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)
|
2022-10-06 22:12:43 +08:00
|
|
|
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
|
2022-10-06 17:58:11 +08:00
|
|
|
}
|