goweb/controller/login.go

96 lines
2.5 KiB
Go

package controller
import (
"fmt"
"github.com/gin-gonic/gin"
. "goweb/core"
. "goweb/global"
"goweb/repository"
"goweb/utils"
"math/rand"
"net/http"
"time"
)
// GetSmsCodeController 获取登录验证码
func GetSmsCodeController(ctx *gin.Context) {
type requestBody struct {
Phone string `json:"phone"`
}
// 取出并判断设备指纹是否存在
deviceId := ctx.GetHeader("di")
// 取出手机号
var params requestBody
err := ctx.ShouldBindJSON(&params)
if err != nil {
Log.Errorf("[发送短信验证码]读取参数错误: %v", err.Error())
R(ctx).FailWithMessage("参数错误")
return
}
phone := params.Phone
Log.Debugf("设备指纹: %v -----> 手机号: %v", deviceId, phone)
// 判断设备是否发送过
phoneKey := fmt.Sprintf("auth:sms:phone:%v", phone)
flag := RedisConn.ExistKey(phoneKey)
if flag {
R(ctx).FailWithMessage("发送间隔过短,请稍后重试")
return
}
// 开始发送短信
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
code := fmt.Sprintf("%06v", rnd.Int31n(1000000))
// 发送
flag = AliSmsBot.SentSms(phone, code)
if !flag {
R(ctx).FailWithMessage("验证码发送失败,请稍后重试")
return
}
err = RedisConn.SetWithTimeout(phoneKey, code, "600")
if err != nil {
Log.Errorf("保存验证码到Redis失败: %v", err.Error())
R(ctx).FailWithMessage("验证码发送失败,请稍后重试")
return
}
R(ctx).OkWithMessage("验证码已发送,有效期十分钟,请尽快使用")
}
// LoginController 登录
func LoginController(ctx *gin.Context) {
type loginParams struct {
Phone string
Code string
}
var params loginParams
if err := ctx.ShouldBindJSON(&params); err != nil {
R(ctx).FailWithMessage("参数错误")
return
}
phoneKey := fmt.Sprintf("auth:sms:phone:%v", params.Phone)
if !RedisConn.ExistKey(phoneKey) {
R(ctx).FailWithMessageAndCode("未发送验证码或已过期", http.StatusForbidden)
return
}
cacheCode, err := RedisConn.GetData(phoneKey)
if err != nil {
R(ctx).FailWithMessage("系统异常")
return
}
if cacheCode != params.Code {
R(ctx).FailWithMessageAndCode("验证码错误", http.StatusForbidden)
return
}
// 验证通过,查询数据库数据
ur := repository.NewUserRepository()
dbUser, err := ur.GetUserByPhone(params.Phone)
if err != nil {
Log.Errorf("用户数据获取失败: %v", err.Error())
R(ctx).FailWithMessage("系统错误")
return
}
token := utils.GenerateToken(dbUser.ID)
result := map[string]interface{}{}
result["token"] = token
R(ctx).OkDetailed(result, "登录成功")
}