108 lines
2.1 KiB
Go
108 lines
2.1 KiB
Go
package handlers
|
|
|
|
import (
|
|
"errors"
|
|
"platform/web/models"
|
|
q "platform/web/queries"
|
|
"platform/web/services"
|
|
"time"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type LoginReq struct {
|
|
Username string `json:"username"`
|
|
Password string `json:"password"`
|
|
Remember bool `json:"remember"`
|
|
}
|
|
|
|
type LoginResp struct {
|
|
Token string `json:"token"`
|
|
Expires int64 `json:"expires"`
|
|
}
|
|
|
|
func Login(c *fiber.Ctx) error {
|
|
|
|
// 验证请求参数
|
|
req := new(LoginReq)
|
|
if err := c.BodyParser(req); err != nil {
|
|
return err
|
|
}
|
|
if req.Username == "" {
|
|
return fiber.NewError(fiber.StatusBadRequest, "手机号不能为空")
|
|
}
|
|
if req.Password == "" {
|
|
return fiber.NewError(fiber.StatusBadRequest, "验证码不能为空")
|
|
}
|
|
|
|
return loginByPhone(c, req)
|
|
}
|
|
|
|
func loginByPhone(c *fiber.Ctx, req *LoginReq) error {
|
|
|
|
// 验证验证码
|
|
err := services.Verifier.VerifySms(c.Context(), req.Username, req.Password)
|
|
if err != nil {
|
|
if errors.Is(err, services.ErrVerifierServiceInvalid) {
|
|
return fiber.NewError(fiber.StatusBadRequest, "验证码错误")
|
|
}
|
|
return err
|
|
}
|
|
|
|
// 查找用户 todo 获取权限信息
|
|
var tx = q.Q.Begin()
|
|
|
|
var user *models.User
|
|
user, err = tx.User.
|
|
Where(tx.User.Phone.Eq(req.Username)).
|
|
Take()
|
|
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return err
|
|
}
|
|
|
|
// 如果用户不存在,初始化用户 todo 保存默认权限信息
|
|
if user == nil {
|
|
user = &models.User{
|
|
Phone: req.Username,
|
|
}
|
|
}
|
|
|
|
// 更新用户的登录时间
|
|
user.LastLogin = time.Now()
|
|
user.LastLoginHost = c.IP()
|
|
user.LastLoginAgent = c.Get("User-Agent")
|
|
if err := tx.User.Omit(q.User.AdminID).Save(user); err != nil {
|
|
return err
|
|
}
|
|
|
|
err = tx.Commit()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// 保存到会话
|
|
auth := services.AuthContext{
|
|
Permissions: map[string]struct{}{
|
|
"user": {},
|
|
},
|
|
Payload: services.Payload{
|
|
Type: services.PayloadUser,
|
|
Id: user.ID,
|
|
},
|
|
}
|
|
duration := time.Hour * 24
|
|
if req.Remember {
|
|
duration *= 7
|
|
}
|
|
token, err := services.Session.Create(c.Context(), auth)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return c.JSON(LoginResp{
|
|
Token: token.AccessToken,
|
|
Expires: token.AccessTokenExpires.Unix(),
|
|
})
|
|
}
|