192 lines
5.0 KiB
Go
192 lines
5.0 KiB
Go
package service
|
|
|
|
import (
|
|
"ai-gateway/common/constant"
|
|
"ai-gateway/common/dto"
|
|
"ai-gateway/common/email"
|
|
"ai-gateway/common/utils"
|
|
"ai-gateway/infrastructure/redis"
|
|
"ai-gateway/infrastructure/repository"
|
|
"context"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"errors"
|
|
"github.com/google/uuid"
|
|
"github.com/labstack/echo/v4"
|
|
"golang.org/x/time/rate"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type login struct {
|
|
}
|
|
|
|
var Login login
|
|
|
|
// 令牌桶大小为 100, 以每秒 10 个 Token 的速率向桶中放置 Token
|
|
var limiter = rate.NewLimiter(10, 10)
|
|
|
|
// Register 注册
|
|
func (l login) Register(ctx context.Context, req dto.ThirdRegisterReq) error {
|
|
acUser := repository.GUser.FindByAccount(ctx, req.Account)
|
|
if acUser != nil && acUser.Deleted == 0 {
|
|
return errors.New("user exist")
|
|
}
|
|
|
|
var user repository.AccountDO
|
|
user.Name = req.Name
|
|
user.Avatar = req.Icon
|
|
|
|
user.Email = req.Account
|
|
//密码加密
|
|
h := sha256.Sum256([]byte(req.Password))
|
|
passHash := hex.EncodeToString(h[:])
|
|
user.Pwd = passHash
|
|
|
|
repository.GUser.Create(ctx, &user)
|
|
return nil
|
|
}
|
|
|
|
func (l login) Login(ctx context.Context, req dto.ThirdLoginReq) (string, error) {
|
|
//1. 验证账号密码
|
|
h := sha256.Sum256([]byte(req.Password))
|
|
passHash := hex.EncodeToString(h[:])
|
|
|
|
acUser := repository.GUser.FindByAccount(ctx, req.Account)
|
|
if acUser == nil || acUser.Deleted == 1 {
|
|
return "", errors.New("user not exist")
|
|
}
|
|
if passHash != acUser.Pwd {
|
|
return "", errors.New("password is error")
|
|
}
|
|
|
|
//生成token
|
|
token := uuid.New().String()
|
|
token = strings.ReplaceAll(token, "-", "")
|
|
var thirdUserToken = repository.GLoginToken{
|
|
Uid: acUser.Id,
|
|
AccessToken: token,
|
|
ExpireTime: time.Now().Add(time.Duration(24*365*100) * time.Hour).UnixMilli(),
|
|
}
|
|
|
|
gUserToken := repository.GUserToken.FindByUid(ctx, acUser.Id)
|
|
if gUserToken == nil {
|
|
repository.GUserToken.SaveUserLoginToken(ctx, &thirdUserToken)
|
|
return l.GenAccessToken(&thirdUserToken), nil
|
|
}
|
|
|
|
gUserToken.AccessToken = thirdUserToken.AccessToken
|
|
gUserToken.ExpireTime = thirdUserToken.ExpireTime
|
|
repository.GUserToken.UpdateUserLoginToken(ctx, gUserToken)
|
|
return l.GenAccessToken(gUserToken), nil
|
|
}
|
|
|
|
func (l login) SendResetPwdCode(ctx context.Context, account string) error {
|
|
//1. 验证账号
|
|
acUser := repository.GUser.FindByAccount(ctx, account)
|
|
if acUser == nil || acUser.Deleted == 1 {
|
|
return errors.New("user not exist")
|
|
}
|
|
|
|
//2. 生成code & 发送
|
|
code := utils.GetPseudoRandomCode(6)
|
|
|
|
//3. save into redis
|
|
if err := redis.Set(constant.G_RESET_PWD_CODE+account, code, time.Duration(30)*time.Minute); err != nil {
|
|
return errors.New("cache illegal")
|
|
}
|
|
|
|
//频控
|
|
if !limiter.Allow() {
|
|
return errors.New("rate limit, please try again later")
|
|
}
|
|
|
|
//4. send code
|
|
if err := email.SendEmailVerifyCodeByEmail(code, account); err != nil {
|
|
return errors.New("send email code illegal")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ResetPwd 重置密码
|
|
func (l login) ResetPwd(ctx context.Context, req dto.ThirdResetPwdReq) error {
|
|
//1. 验证code
|
|
redisStr, err := redis.Get(constant.G_RESET_PWD_CODE + req.Account)
|
|
if err != nil && redisStr != req.Code {
|
|
return errors.New("code is error")
|
|
}
|
|
|
|
//2. 查询用户
|
|
acUser := repository.GUser.FindByAccount(ctx, req.Account)
|
|
if acUser == nil || acUser.Deleted == 1 {
|
|
return errors.New("user not exist")
|
|
}
|
|
|
|
//3. 重置密码
|
|
h := sha256.Sum256([]byte(req.Password))
|
|
passHash := hex.EncodeToString(h[:])
|
|
acUser.Pwd = passHash
|
|
repository.GUser.UpdateById(ctx, acUser)
|
|
|
|
//生成token
|
|
token := uuid.New().String()
|
|
token = strings.ReplaceAll(token, "-", "")
|
|
var thirdUserToken = repository.GLoginToken{
|
|
Uid: acUser.Id,
|
|
Platform: "web",
|
|
AccessToken: token,
|
|
ExpireTime: time.Now().Add(time.Duration(24*365*100) * time.Hour).UnixMilli(),
|
|
}
|
|
|
|
loginUserToken := repository.GUserToken.FindByUid(ctx, acUser.Id)
|
|
if loginUserToken == nil {
|
|
repository.GUserToken.SaveUserLoginToken(ctx, &thirdUserToken)
|
|
return nil
|
|
}
|
|
|
|
loginUserToken.AccessToken = thirdUserToken.AccessToken
|
|
loginUserToken.ExpireTime = thirdUserToken.ExpireTime
|
|
repository.GUserToken.UpdateUserLoginToken(ctx, loginUserToken)
|
|
return nil
|
|
}
|
|
|
|
func (l login) GetLoginResult(ctx context.Context, c *echo.Context) *dto.ThirdUserLoginToken {
|
|
accessToken := utils.GetAccessToken(c)
|
|
if accessToken == "" {
|
|
return nil
|
|
}
|
|
|
|
//redis
|
|
redisStr, err := redis.Get(constant.THIRD_LOGIN_TOKEN + accessToken)
|
|
if err != nil && redisStr != "" {
|
|
var loginInfo dto.ThirdUserLoginToken
|
|
if redisErr := json.Unmarshal([]byte(redisStr), &loginInfo); redisErr == nil {
|
|
return &loginInfo
|
|
}
|
|
}
|
|
|
|
//repository
|
|
dbData := repository.GUserToken.FindByToken(ctx, accessToken)
|
|
if dbData == nil {
|
|
return nil
|
|
}
|
|
|
|
var finalData = dto.ThirdUserLoginToken{
|
|
Uid: dbData.Uid,
|
|
AccessToken: l.GenAccessToken(dbData),
|
|
}
|
|
|
|
//save into redis
|
|
if bytes, saveErr := json.Marshal(finalData); saveErr == nil {
|
|
redis.Set(constant.THIRD_LOGIN_TOKEN+accessToken, string(bytes), time.Duration(6)*time.Hour)
|
|
}
|
|
|
|
return &finalData
|
|
}
|
|
|
|
func (login) GenAccessToken(data *repository.GLoginToken) string {
|
|
return data.AccessToken
|
|
}
|