Feat: 2-FA login verification

This commit is contained in:
HFO4
2020-02-21 13:48:34 +08:00
parent 11e45bc751
commit 7c07b623f6
6 changed files with 93 additions and 1 deletions

View File

@@ -6,6 +6,7 @@ import (
"github.com/HFO4/cloudreve/pkg/util"
"github.com/gin-gonic/gin"
"github.com/mojocn/base64Captcha"
"github.com/pquerna/otp/totp"
)
// UserLoginService 管理用户登录的服务
@@ -16,6 +17,32 @@ type UserLoginService struct {
CaptchaCode string `form:"captchaCode" json:"captchaCode"`
}
// Login 二步验证继续登录
func (service *Enable2FA) Login(c *gin.Context) serializer.Response {
if uid, ok := util.GetSession(c, "2fa_user_id").(uint); ok {
// 查找用户
expectedUser, err := model.GetActiveUserByID(uid)
if err != nil {
return serializer.Err(serializer.CodeNotFound, "用户不存在", nil)
}
// 验证二步验证代码
if !totp.Validate(service.Code, expectedUser.TwoFactor) {
return serializer.ParamErr("验证代码不正确", nil)
}
//登陆成功清空并设置session
util.DeleteSession(c, "2fa_user_id")
util.SetSession(c, map[string]interface{}{
"user_id": expectedUser.ID,
})
return serializer.BuildUserResponse(expectedUser)
}
return serializer.Err(serializer.CodeNotFound, "登录会话不存在", nil)
}
// Login 用户登录函数
func (service *UserLoginService) Login(c *gin.Context) serializer.Response {
isCaptchaRequired := model.GetSettingByName("login_captcha")
@@ -44,7 +71,11 @@ func (service *UserLoginService) Login(c *gin.Context) serializer.Response {
}
if expectedUser.TwoFactor != "" {
//TODO 二步验证处理
// 需要二步验证
util.SetSession(c, map[string]interface{}{
"2fa_user_id": expectedUser.ID,
})
return serializer.Response{Code: 203}
}
//登陆成功清空并设置session

View File

@@ -16,11 +16,14 @@ type QQCallbackService struct {
// Callback 处理QQ互联回调
func (service *QQCallbackService) Callback(c *gin.Context, user *model.User) serializer.Response {
state := util.GetSession(c, "qq_login_secret")
if stateStr, ok := state.(string); !ok || stateStr != service.State {
return serializer.Err(serializer.CodeSignExpired, "请求过期,请重试", nil)
}
util.DeleteSession(c, "qq_login_secret")
// 获取OpenID
credential, err := qq.Callback(service.Code)
if err != nil {
return serializer.Err(serializer.CodeNotSet, "无法获取登录状态", err)
@@ -28,6 +31,7 @@ func (service *QQCallbackService) Callback(c *gin.Context, user *model.User) ser
// 如果已登录,则绑定已有用户
if user != nil {
if user.OpenID != "" {
return serializer.Err(serializer.CodeCallbackError, "您已绑定了QQ账号请先解除绑定", nil)
}
@@ -37,6 +41,21 @@ func (service *QQCallbackService) Callback(c *gin.Context, user *model.User) ser
return serializer.Response{
Data: "/setting",
}
}
// 未登录,尝试查找用户
if expectedUser, err := model.GetActiveUserByOpenID(credential.OpenID); err == nil {
// 用户绑定了此QQ设定为登录状态
util.SetSession(c, map[string]interface{}{
"user_id": expectedUser.ID,
})
res := serializer.BuildUserResponse(expectedUser)
res.Code = 203
return res
} else {
// 无匹配用户,创建新用户
}
return serializer.Response{}