add comment verification

This commit is contained in:
landaiqing
2024-09-26 01:13:06 +08:00
parent 97175c3d67
commit 372835296d
14 changed files with 228 additions and 98 deletions

View File

@@ -239,12 +239,12 @@ func (CaptchaAPI) GenerateClickShapeCaptcha(c *gin.Context) {
result.OkWithData(bt, c)
}
// GenerateSlideBasicCaptData 生成点击形状基础验证码
// @Summary 生成点击形状基础验证码
// @Description 生成点击形状基础验证码
// @Tags 点击形状验证码
// GenerateSlideBasicCaptData 滑块基础验证码
// @Summary 滑块基础验证码
// @Description 滑块基础验证码
// @Tags 滑块基础验证码
// @Success 200 {string} json
// @Router /api/captcha/shape/check [get]
// @Router /api/captcha/slide/generate [get]
func (CaptchaAPI) GenerateSlideBasicCaptData(c *gin.Context) {
captData, err := global.SlideCaptcha.Generate()
if err != nil {
@@ -266,70 +266,27 @@ func (CaptchaAPI) GenerateSlideBasicCaptData(c *gin.Context) {
return
}
key := helper.StringToMD5(string(dotsByte))
err = redis.Set(key, dotsByte, time.Minute).Err()
err = redis.Set(constant.CommentSubmitCaptchaRedisKey+key, dotsByte, time.Minute).Err()
if err != nil {
result.FailWithNull(c)
return
}
bt := map[string]interface{}{
"key": key,
"image": masterImageBase64,
"tile": tileImageBase64,
"tile_width": blockData.Width,
"tile_height": blockData.Height,
"tile_x": blockData.TileX,
"tile_y": blockData.TileY,
"key": key,
"image": masterImageBase64,
"thumb": tileImageBase64,
"thumb_width": blockData.Width,
"thumb_height": blockData.Height,
"thumb_x": blockData.TileX,
"thumb_y": blockData.TileY,
}
result.OkWithData(bt, c)
}
// CheckSlideData 验证点击形状验证码
// @Summary 验证点击形状验证码
// @Description 验证点击形状验证码
// @Tags 点击形状验证码
// @Param point query string true "点击坐标"
// @Param key query string true "验证码key"
// @Success 200 {string} json
// @Router /api/captcha/shape/slide/check [get]
func (CaptchaAPI) CheckSlideData(c *gin.Context) {
point := c.Query("point")
key := c.Query("key")
if point == "" || key == "" {
result.FailWithNull(c)
return
}
cacheDataByte, err := redis.Get(key).Bytes()
if len(cacheDataByte) == 0 || err != nil {
result.FailWithNull(c)
return
}
src := strings.Split(point, ",")
var dct *slide.Block
if err := json.Unmarshal(cacheDataByte, &dct); err != nil {
result.FailWithNull(c)
return
}
chkRet := false
if 2 == len(src) {
sx, _ := strconv.ParseFloat(fmt.Sprintf("%v", src[0]), 64)
sy, _ := strconv.ParseFloat(fmt.Sprintf("%v", src[1]), 64)
chkRet = slide.CheckPoint(int64(sx), int64(sy), int64(dct.X), int64(dct.Y), 4)
}
if chkRet {
result.OkWithMessage("success", c)
return
}
result.FailWithMessage("fail", c)
}
// GenerateSlideRegionCaptData 生成点击形状验证码
// @Summary 生成点击形状验证码
// @Description 生成点击形状验证码
// @Tags 点击形状验证码
// GenerateSlideRegionCaptData 生成滑动区域形状验证码
// @Summary 生成滑动区域形状验证码
// @Description 生成滑动区域形状验证码
// @Tags 生成滑动区域形状验证码
// @Success 200 {string} json
// @Router /api/captcha/shape/slide/region/get [get]
func (CaptchaAPI) GenerateSlideRegionCaptData(c *gin.Context) {
@@ -371,3 +328,46 @@ func (CaptchaAPI) GenerateSlideRegionCaptData(c *gin.Context) {
}
result.OkWithData(bt, c)
}
// CheckSlideData 验证滑动验证码
// @Summary 验证滑动验证码
// @Description 验证滑动验证码
// @Tags 验证滑动验证码
// @Param point query string true "点击坐标"
// @Param key query string true "验证码key"
// @Success 200 {string} json
// @Router /api/captcha/shape/slide/check [get]
func (CaptchaAPI) CheckSlideData(c *gin.Context) {
point := c.Query("point")
key := c.Query("key")
if point == "" || key == "" {
result.FailWithNull(c)
return
}
cacheDataByte, err := redis.Get(key).Bytes()
if len(cacheDataByte) == 0 || err != nil {
result.FailWithNull(c)
return
}
src := strings.Split(point, ",")
var dct *slide.Block
if err := json.Unmarshal(cacheDataByte, &dct); err != nil {
result.FailWithNull(c)
return
}
chkRet := false
if 2 == len(src) {
sx, _ := strconv.ParseFloat(fmt.Sprintf("%v", src[0]), 64)
sy, _ := strconv.ParseFloat(fmt.Sprintf("%v", src[1]), 64)
chkRet = slide.CheckPoint(int64(sx), int64(sy), int64(dct.X), int64(dct.Y), 4)
}
if chkRet {
result.OkWithMessage("success", c)
return
}
result.FailWithMessage("fail", c)
}

View File

@@ -30,9 +30,15 @@ import (
func (CommentAPI) CommentSubmit(c *gin.Context) {
commentRequest := dto.CommentRequest{}
if err := c.ShouldBindJSON(&commentRequest); err != nil {
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
return
}
// 验证校验
res := utils.CheckSlideData(commentRequest.Point, commentRequest.Key)
if !res {
result.FailWithMessage(ginI18n.MustGetMessage(c, "CaptchaVerifyError"), c)
return
}
if len(commentRequest.Images) > 3 {
result.FailWithMessage(ginI18n.MustGetMessage(c, "TooManyImages"), c)
return
@@ -148,7 +154,12 @@ func (CommentAPI) ReplySubmit(c *gin.Context) {
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
return
}
// 验证校验
res := utils.CheckSlideData(replyCommentRequest.Point, replyCommentRequest.Key)
if !res {
result.FailWithMessage(ginI18n.MustGetMessage(c, "CaptchaVerifyError"), c)
return
}
if len(replyCommentRequest.Images) > 3 {
result.FailWithMessage(ginI18n.MustGetMessage(c, "TooManyImages"), c)
return
@@ -270,7 +281,12 @@ func (CommentAPI) ReplyReplySubmit(c *gin.Context) {
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
return
}
// 验证校验
res := utils.CheckSlideData(replyReplyRequest.Point, replyReplyRequest.Key)
if !res {
result.FailWithMessage(ginI18n.MustGetMessage(c, "CaptchaVerifyError"), c)
return
}
if len(replyReplyRequest.Images) > 3 {
result.FailWithMessage(ginI18n.MustGetMessage(c, "TooManyImages"), c)
return
@@ -394,7 +410,12 @@ func (CommentAPI) CommentList(c *gin.Context) {
// 查询评论列表
query, u := gplus.NewQuery[model.ScaCommentReply]()
page := gplus.NewPage[model.ScaCommentReply](commentListRequest.Page, commentListRequest.Size)
query.Eq(&u.TopicId, commentListRequest.TopicId).Eq(&u.CommentType, enum.COMMENT).OrderByDesc(&u.CommentOrder).OrderByDesc(&u.Likes).OrderByDesc(&u.ReplyCount).OrderByDesc(&u.CreatedTime)
if commentListRequest.IsHot {
query.OrderByDesc(&u.CommentOrder).OrderByDesc(&u.Likes).OrderByDesc(&u.ReplyCount)
} else {
query.OrderByDesc(&u.CommentOrder).OrderByDesc(&u.CreatedTime)
}
query.Eq(&u.TopicId, commentListRequest.TopicId).Eq(&u.CommentType, enum.COMMENT)
page, pageDB := gplus.SelectPage(page, query)
if pageDB.Error != nil {
global.LOG.Errorln(pageDB.Error)
@@ -455,7 +476,7 @@ func (CommentAPI) CommentList(c *gin.Context) {
// 查询评论图片信息
go func() {
defer wg.Done()
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) // 设置超时2秒
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) // 设置超时2秒
defer cancel()
cursor, err := global.MongoDB.Database(global.CONFIG.MongoDB.DB).Collection("comment_images").Find(ctx, bson.M{"comment_id": bson.M{"$in": commentIds}})
@@ -563,7 +584,7 @@ func (CommentAPI) ReplyList(c *gin.Context) {
}
query, u := gplus.NewQuery[model.ScaCommentReply]()
page := gplus.NewPage[model.ScaCommentReply](replyListRequest.Page, replyListRequest.Size)
query.Eq(&u.TopicId, replyListRequest.TopicId).Eq(&u.ReplyId, replyListRequest.CommentId).Eq(&u.CommentType, enum.REPLY).OrderByDesc(&u.CommentOrder).OrderByDesc(&u.Likes).OrderByDesc(&u.CreatedTime)
query.Eq(&u.TopicId, replyListRequest.TopicId).Eq(&u.ReplyId, replyListRequest.CommentId).Eq(&u.CommentType, enum.REPLY).OrderByDesc(&u.Likes).OrderByAsc(&u.CreatedTime)
page, pageDB := gplus.SelectPage(page, query)
if pageDB.Error != nil {
global.LOG.Errorln(pageDB.Error)

View File

@@ -6,6 +6,8 @@ type CommentRequest struct {
UserID string `json:"user_id" binding:"required"`
TopicId string `json:"topic_id" binding:"required"`
Author string `json:"author" binding:"required"`
Key string `json:"key" binding:"required"`
Point []int64 `json:"point" binding:"required"`
}
type ReplyCommentRequest struct {
Content string `json:"content" binding:"required"`
@@ -15,6 +17,8 @@ type ReplyCommentRequest struct {
ReplyId int64 `json:"reply_id" binding:"required"`
ReplyUser string `json:"reply_user" binding:"required"`
Author string `json:"author" binding:"required"`
Key string `json:"key" binding:"required"`
Point []int64 `json:"point" binding:"required"`
}
type ReplyReplyRequest struct {
@@ -26,6 +30,8 @@ type ReplyReplyRequest struct {
ReplyId int64 `json:"reply_id" binding:"required"`
ReplyUser string `json:"reply_user" binding:"required"`
Author string `json:"author" binding:"required"`
Key string `json:"key" binding:"required"`
Point []int64 `json:"point" binding:"required"`
}
type CommentListRequest struct {
@@ -33,6 +39,7 @@ type CommentListRequest struct {
TopicId string `json:"topic_id" binding:"required"`
Page int `json:"page" default:"1"`
Size int `json:"size" default:"5"`
IsHot bool `json:"is_hot" default:"true"`
}
type ReplyListRequest struct {
UserID string `json:"user_id" binding:"required"`

View File

@@ -11,6 +11,7 @@ import (
"schisandra-cloud-album/api/user_api/dto"
"schisandra-cloud-album/common/constant"
"schisandra-cloud-album/common/redis"
"schisandra-cloud-album/common/result"
"schisandra-cloud-album/global"
"schisandra-cloud-album/model"
"schisandra-cloud-album/service"
@@ -39,10 +40,11 @@ var script = `
`
func HandleLoginResponse(c *gin.Context, uid string) {
res, data := HandelUserLogin(uid)
res, data := HandelUserLogin(uid, c)
if !res {
return
}
tokenData, err := json.Marshal(data)
if err != nil {
global.LOG.Error(err)
@@ -55,7 +57,7 @@ func HandleLoginResponse(c *gin.Context, uid string) {
}
// HandelUserLogin 处理用户登录
func HandelUserLogin(userId string) (bool, map[string]interface{}) {
func HandelUserLogin(userId string, c *gin.Context) (bool, result.Response) {
// 使用goroutine生成accessToken
accessTokenChan := make(chan string)
errChan := make(chan error)
@@ -86,7 +88,7 @@ func HandelUserLogin(userId string) (bool, map[string]interface{}) {
case accessToken = <-accessTokenChan:
case err = <-errChan:
global.LOG.Error(err)
return false, nil
return false, result.Response{}
}
select {
case refreshToken = <-refreshTokenChan:
@@ -99,7 +101,10 @@ func HandelUserLogin(userId string) (bool, map[string]interface{}) {
ExpiresAt: expiresAt,
UID: &userId,
}
wrong := utils.SetSession(c, "user", data)
if wrong != nil {
return false, result.Response{}
}
// 使用goroutine将数据存入redis
redisErrChan := make(chan error)
go func() {
@@ -115,13 +120,13 @@ func HandelUserLogin(userId string) (bool, map[string]interface{}) {
redisErr := <-redisErrChan
if redisErr != nil {
global.LOG.Error(redisErr)
return false, nil
return false, result.Response{}
}
responseData := map[string]interface{}{
"code": 0,
"message": "success",
"data": data,
"success": true,
responseData := result.Response{
Data: data,
Message: "success",
Code: 200,
Success: true,
}
return true, responseData
}

View File

@@ -1,6 +1,7 @@
package oauth_api
import (
"encoding/gob"
"encoding/json"
"errors"
"github.com/ArtisanCloud/PowerLibs/v3/http/helper"
@@ -47,7 +48,7 @@ func (OAuthAPI) CallbackNotify(c *gin.Context) {
return "error"
}
key := strings.TrimPrefix(msg.EventKey, "qrscene_")
res := wechatLoginHandler(msg.FromUserName, key)
res := wechatLoginHandler(msg.FromUserName, key, c)
if !res {
return messages.NewText(ginI18n.MustGetMessage(c, "LoginFailed"))
}
@@ -69,7 +70,7 @@ func (OAuthAPI) CallbackNotify(c *gin.Context) {
println(err.Error())
return "error"
}
res := wechatLoginHandler(msg.FromUserName, msg.EventKey)
res := wechatLoginHandler(msg.FromUserName, msg.EventKey, c)
if !res {
return messages.NewText(ginI18n.MustGetMessage(c, "LoginFailed"))
}
@@ -165,7 +166,7 @@ func (OAuthAPI) GetTempQrCode(c *gin.Context) {
}
// wechatLoginHandler 微信登录处理
func wechatLoginHandler(openId string, clientId string) bool {
func wechatLoginHandler(openId string, clientId string, c *gin.Context) bool {
if openId == "" {
return false
}
@@ -257,7 +258,7 @@ func wechatLoginHandler(openId string, clientId string) bool {
// 异步处理用户登录
resChan := make(chan bool, 1)
go func() {
res := handelUserLogin(*addUser.UID, clientId)
res := handelUserLogin(*addUser.UID, clientId, c)
resChan <- res
}()
@@ -271,7 +272,7 @@ func wechatLoginHandler(openId string, clientId string) bool {
tx.Commit()
return true
} else {
res := handelUserLogin(*authUserSocial.UserID, clientId)
res := handelUserLogin(*authUserSocial.UserID, clientId, c)
if !res {
return false
}
@@ -280,7 +281,7 @@ func wechatLoginHandler(openId string, clientId string) bool {
}
// handelUserLogin 处理用户登录
func handelUserLogin(userId string, clientId string) bool {
func handelUserLogin(userId string, clientId string, c *gin.Context) bool {
resultChan := make(chan bool, 1)
go func() {
@@ -312,6 +313,12 @@ func handelUserLogin(userId string, clientId string) bool {
resultChan <- false
return
}
gob.Register(dto.ResponseData{})
wrong := utils.SetSession(c, "user", data)
if wrong != nil {
resultChan <- false
return
}
// gws方式发送消息
err = websocket_api.Handler.SendMessageToClient(clientId, tokenData)
if err != nil {

View File

@@ -1,6 +1,7 @@
package user_api
import (
"encoding/gob"
"errors"
ginI18n "github.com/gin-contrib/i18n"
"github.com/gin-gonic/gin"
@@ -332,6 +333,7 @@ func handelUserLogin(user model.ScaAuthUser, autoLogin bool, c *gin.Context) {
result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c)
return
}
gob.Register(dto.ResponseData{})
err = utils.SetSession(c, "user", data)
if err != nil {
result.FailWithMessage(ginI18n.MustGetMessage(c, "LoginFailed"), c)