2024-07-05 14:41:35 +08:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"gitee.ltd/lxh/logger/log"
|
|
|
|
"github.com/gin-gonic/gin"
|
2024-07-12 11:06:14 +08:00
|
|
|
"github.com/google/uuid"
|
2024-07-05 14:41:35 +08:00
|
|
|
"github.com/mojocn/base64Captcha"
|
2024-07-12 11:06:14 +08:00
|
|
|
"time"
|
2024-07-05 14:41:35 +08:00
|
|
|
"wireguard-ui/component"
|
|
|
|
"wireguard-ui/http/param"
|
|
|
|
"wireguard-ui/http/response"
|
2024-08-06 14:49:05 +08:00
|
|
|
"wireguard-ui/http/vo"
|
2024-07-05 14:41:35 +08:00
|
|
|
"wireguard-ui/service"
|
|
|
|
"wireguard-ui/utils"
|
|
|
|
)
|
|
|
|
|
|
|
|
type LoginApi struct{}
|
|
|
|
|
|
|
|
func Login() LoginApi {
|
|
|
|
return LoginApi{}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Captcha
|
|
|
|
// @description: 获取验证码
|
|
|
|
// @receiver login
|
|
|
|
// @param c
|
|
|
|
func (LoginApi) Captcha(c *gin.Context) {
|
|
|
|
math := base64Captcha.DriverMath{Height: 120, Width: 480, Fonts: []string{"ApothecaryFont.ttf", "3Dumb.ttf"}}
|
|
|
|
mathDriver := math.ConvertFonts()
|
|
|
|
|
|
|
|
capt := base64Captcha.NewCaptcha(mathDriver, component.Captcha{})
|
|
|
|
|
|
|
|
id, base64Str, _, err := capt.Generate()
|
|
|
|
if err != nil {
|
|
|
|
response.R(c).FailedWithError(fmt.Errorf("生成验证码失败: %s", err.Error()))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
response.R(c).OkWithData(map[string]any{
|
|
|
|
"id": id,
|
|
|
|
"captcha": base64Str,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Login
|
|
|
|
// @description: 登陆
|
|
|
|
// @receiver login
|
|
|
|
// @param c
|
|
|
|
func (LoginApi) Login(c *gin.Context) {
|
|
|
|
var p param.Login
|
|
|
|
if err := c.ShouldBind(&p); err != nil {
|
|
|
|
response.R(c).Validator(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// 验证验证码是否正确
|
|
|
|
ok := component.Captcha{}.Verify(p.CaptchaId, p.CaptchaCode, true)
|
|
|
|
if !ok {
|
|
|
|
response.R(c).FailedWithError("验证码错误")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// 验证码正确,查询用户信息
|
|
|
|
user, err := service.User().GetUserByAccount(p.Account)
|
|
|
|
if err != nil {
|
|
|
|
response.R(c).FailedWithError("获取用户信息失败")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// 对比密码
|
|
|
|
if !utils.Password().ComparePassword(user.Password, p.Password) {
|
|
|
|
response.R(c).FailedWithError("密码错误")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-07-12 11:06:14 +08:00
|
|
|
secret := component.JWT().GenerateSecret(p.Password, uuid.NewString(), time.Now().Local().String())
|
2024-07-05 14:41:35 +08:00
|
|
|
// 生成token
|
2024-07-12 11:06:14 +08:00
|
|
|
token, expireAt, err := component.JWT().GenerateToken(user.Id, secret)
|
2024-07-05 14:41:35 +08:00
|
|
|
if err != nil {
|
|
|
|
log.Errorf("用户[%s]生成token失败: %v", user.Account, err.Error())
|
|
|
|
response.R(c).FailedWithError("登陆失败!")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-07-12 11:06:14 +08:00
|
|
|
c.Writer.Header().Set("X-TOKEN", secret)
|
2024-07-05 14:41:35 +08:00
|
|
|
response.R(c).OkWithData(map[string]any{
|
|
|
|
"token": token,
|
|
|
|
"type": "Bearer",
|
|
|
|
"expireAt": expireAt,
|
|
|
|
})
|
|
|
|
}
|
2024-08-06 14:49:05 +08:00
|
|
|
|
|
|
|
// Logout
|
|
|
|
// @description: 退出登陆
|
|
|
|
// @receiver LoginApi
|
|
|
|
// @param c
|
|
|
|
func (LoginApi) Logout(c *gin.Context) {
|
|
|
|
loginUser, ok := c.Get("user")
|
|
|
|
if !ok {
|
|
|
|
response.R(c).AuthorizationFailed("未登陆")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := component.JWT().Logout(loginUser.(*vo.User).Id); err != nil {
|
|
|
|
response.R(c).FailedWithError("退出登陆失败")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
response.R(c).OK()
|
|
|
|
}
|