♻️ refactored login-related code

This commit is contained in:
2024-12-21 00:51:59 +08:00
parent 40d073db0f
commit f213644aa9
33 changed files with 802 additions and 535 deletions

View File

@@ -1,64 +0,0 @@
package oauth
import (
"context"
"encoding/json"
"net/http"
"time"
"github.com/ArtisanCloud/PowerWeChat/v3/src/basicService/qrCode/response"
"schisandra-album-cloud-microservices/app/core/api/common/constant"
response2 "schisandra-album-cloud-microservices/app/core/api/common/response"
"schisandra-album-cloud-microservices/app/core/api/common/utils"
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
"schisandra-album-cloud-microservices/app/core/api/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type GetWechatQrcodeLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewGetWechatQrcodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetWechatQrcodeLogic {
return &GetWechatQrcodeLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *GetWechatQrcodeLogic) GetWechatQrcode(r *http.Request, req *types.OAuthWechatRequest) (resp *types.Response, err error) {
ip := utils.GetClientIP(r) // 使用工具函数获取客户端IP
key := constant.UserQrcodePrefix + ip
// 从Redis获取二维码数据
qrcode := l.svcCtx.RedisClient.Get(l.ctx, key).Val()
if qrcode != "" {
data := new(response.ResponseQRCodeCreate)
if err = json.Unmarshal([]byte(qrcode), data); err != nil {
return nil, err
}
return response2.SuccessWithData(data.Url), nil
}
// 生成临时二维码
data, err := l.svcCtx.WechatPublic.QRCode.Temporary(l.ctx, req.Client_id, 7*24*3600)
if err != nil {
return nil, err
}
// 序列化数据并存储到Redis
serializedData, err := json.Marshal(data)
if err != nil {
return nil, err
}
if err = l.svcCtx.RedisClient.Set(l.ctx, key, serializedData, time.Hour*24*7).Err(); err != nil {
return nil, err
}
return response2.SuccessWithData(data.Url), nil
}

View File

@@ -149,7 +149,7 @@ func (l *GiteeCallbackLogic) GiteeCallback(w http.ResponseWriter, r *http.Reques
_ = tx.Rollback()
return "", err
}
data, err := HandleOauthLoginResponse(addUser, l.svcCtx, r, w, l.ctx)
data, err := HandleOauthLoginResponse(addUser, l.svcCtx, r, l.ctx)
if err != nil {
_ = tx.Rollback()
return "", err
@@ -167,7 +167,7 @@ func (l *GiteeCallbackLogic) GiteeCallback(w http.ResponseWriter, r *http.Reques
return "", err
}
data, err := HandleOauthLoginResponse(authUserInfo, l.svcCtx, r, w, l.ctx)
data, err := HandleOauthLoginResponse(authUserInfo, l.svcCtx, r, l.ctx)
if err != nil {
_ = tx.Rollback()
return "", err
@@ -180,13 +180,12 @@ func (l *GiteeCallbackLogic) GiteeCallback(w http.ResponseWriter, r *http.Reques
}
// HandleOauthLoginResponse 处理登录响应
func HandleOauthLoginResponse(scaAuthUser *model.ScaAuthUser, svcCtx *svc.ServiceContext, r *http.Request, w http.ResponseWriter, ctx context.Context) (string, error) {
data, err := user.HandleUserLogin(scaAuthUser, svcCtx, true, r, w, ctx)
func HandleOauthLoginResponse(scaAuthUser *model.ScaAuthUser, svcCtx *svc.ServiceContext, r *http.Request, ctx context.Context) (string, error) {
data, err := user.HandleLoginJWT(scaAuthUser, svcCtx, true, r, ctx)
if err != nil {
return "", err
}
responseData := response.SuccessWithData(data)
marshalData, err := json.Marshal(responseData)
marshalData, err := json.Marshal(response.SuccessWithData(data))
if err != nil {
return "", err
}

View File

@@ -149,7 +149,7 @@ func (l *GithubCallbackLogic) GithubCallback(w http.ResponseWriter, r *http.Requ
return "", err
}
data, err := HandleOauthLoginResponse(addUser, l.svcCtx, r, w, l.ctx)
data, err := HandleOauthLoginResponse(addUser, l.svcCtx, r, l.ctx)
if err != nil {
_ = tx.Rollback()
return "", err
@@ -167,7 +167,7 @@ func (l *GithubCallbackLogic) GithubCallback(w http.ResponseWriter, r *http.Requ
return "", err
}
data, err := HandleOauthLoginResponse(authUserInfo, l.svcCtx, r, w, l.ctx)
data, err := HandleOauthLoginResponse(authUserInfo, l.svcCtx, r, l.ctx)
if err != nil {
_ = tx.Rollback()
return "", err

View File

@@ -149,7 +149,7 @@ func (l *QqCallbackLogic) QqCallback(w http.ResponseWriter, r *http.Request, req
return "", err
}
data, err := HandleOauthLoginResponse(addUser, l.svcCtx, r, w, l.ctx)
data, err := HandleOauthLoginResponse(addUser, l.svcCtx, r, l.ctx)
if err != nil {
_ = tx.Rollback()
return "", err
@@ -167,7 +167,7 @@ func (l *QqCallbackLogic) QqCallback(w http.ResponseWriter, r *http.Request, req
return "", err
}
data, err := HandleOauthLoginResponse(authUserInfo, l.svcCtx, r, w, l.ctx)
data, err := HandleOauthLoginResponse(authUserInfo, l.svcCtx, r, l.ctx)
if err != nil {
_ = tx.Rollback()
return "", err

View File

@@ -1,208 +0,0 @@
package oauth
import (
"context"
"encoding/json"
"errors"
"net/http"
"strconv"
"strings"
"github.com/ArtisanCloud/PowerLibs/v3/http/helper"
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/contract"
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/messages"
models2 "github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/models"
"github.com/ArtisanCloud/PowerWeChat/v3/src/officialAccount/server/handlers/models"
"github.com/yitter/idgenerator-go/idgen"
"github.com/zeromicro/go-zero/core/logx"
"gorm.io/gorm"
"schisandra-album-cloud-microservices/app/core/api/common/constant"
"schisandra-album-cloud-microservices/app/core/api/common/i18n"
randomname "schisandra-album-cloud-microservices/app/core/api/common/random_name"
"schisandra-album-cloud-microservices/app/core/api/common/utils"
"schisandra-album-cloud-microservices/app/core/api/internal/logic/user"
"schisandra-album-cloud-microservices/app/core/api/internal/logic/websocket"
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
"schisandra-album-cloud-microservices/app/core/api/repository/mysql/model"
)
type WechatCallbackLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewWechatCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WechatCallbackLogic {
return &WechatCallbackLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *WechatCallbackLogic) WechatCallback(w http.ResponseWriter, r *http.Request) error {
_, err := l.svcCtx.WechatPublic.Server.VerifyURL(r)
if err != nil {
return err
}
rs, err := l.svcCtx.WechatPublic.Server.Notify(r, func(event contract.EventInterface) interface{} {
switch event.GetMsgType() {
case models2.CALLBACK_MSG_TYPE_EVENT:
switch event.GetEvent() {
case models.CALLBACK_EVENT_SUBSCRIBE:
msg := models.EventSubscribe{}
err = event.ReadMessage(&msg)
if err != nil {
println(err.Error())
return err
}
key := strings.TrimPrefix(msg.EventKey, "qrscene_")
err = l.HandlerWechatLogin(msg.FromUserName, key, w, r)
if err != nil {
return messages.NewText(i18n.FormatText(l.ctx, "login.loginFailed"))
}
return messages.NewText(i18n.FormatText(l.ctx, "login.loginSuccess"))
case models.CALLBACK_EVENT_UNSUBSCRIBE:
msg := models.EventUnSubscribe{}
err = event.ReadMessage(&msg)
if err != nil {
println(err.Error())
return err
}
return messages.NewText("ok")
case models.CALLBACK_EVENT_SCAN:
msg := models.EventScan{}
err = event.ReadMessage(&msg)
if err != nil {
println(err.Error())
return err
}
err = l.HandlerWechatLogin(msg.FromUserName, msg.EventKey, w, r)
if err != nil {
return messages.NewText(i18n.FormatText(l.ctx, "login.loginFailed"))
}
return messages.NewText(i18n.FormatText(l.ctx, "login.loginSuccess"))
}
case models2.CALLBACK_MSG_TYPE_TEXT:
msg := models.MessageText{}
err = event.ReadMessage(&msg)
if err != nil {
println(err.Error())
return err
}
}
return messages.NewText("ok")
})
if err != nil {
return err
}
err = helper.HttpResponseSend(rs, w)
if err != nil {
return err
}
return nil
}
// HandlerWechatLogin 处理微信登录
func (l *WechatCallbackLogic) HandlerWechatLogin(openId string, clientId string, w http.ResponseWriter, r *http.Request) error {
if openId == "" {
return errors.New("openId is empty")
}
tx := l.svcCtx.DB.Begin()
userSocial := l.svcCtx.DB.ScaAuthUserSocial
socialUser, err := tx.ScaAuthUserSocial.Where(userSocial.OpenID.Eq(openId), userSocial.Source.Eq(constant.OAuthSourceWechat)).First()
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return err
}
if socialUser == nil {
// 创建用户
uid := idgen.NextId()
uidStr := strconv.FormatInt(uid, 10)
avatar := utils.GenerateAvatar(uidStr)
name := randomname.GenerateName()
male := constant.Male
addUser := &model.ScaAuthUser{
UID: uidStr,
Avatar: avatar,
Username: openId,
Nickname: name,
Gender: male,
}
err = tx.ScaAuthUser.Create(addUser)
if err != nil {
_ = tx.Rollback()
return err
}
wechatUser := constant.OAuthSourceWechat
newSocialUser := &model.ScaAuthUserSocial{
UserID: uidStr,
OpenID: openId,
Source: wechatUser,
}
err = tx.ScaAuthUserSocial.Create(newSocialUser)
if err != nil {
_ = tx.Rollback()
return err
}
if res, err := l.svcCtx.CasbinEnforcer.AddRoleForUser(uidStr, constant.User); !res || err != nil {
_ = tx.Rollback()
return err
}
data, err := user.HandleUserLogin(addUser, l.svcCtx, true, r, w, l.ctx)
if err != nil {
_ = tx.Rollback()
return err
}
marshal, err := json.Marshal(data)
if err != nil {
_ = tx.Rollback()
return err
}
err = websocket.QrcodeWebSocketHandler.SendMessageToClient(clientId, marshal)
if err != nil {
_ = tx.Rollback()
return err
}
} else {
authUser := l.svcCtx.DB.ScaAuthUser
authUserInfo, err := tx.ScaAuthUser.Where(authUser.UID.Eq(socialUser.UserID)).First()
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
_ = tx.Rollback()
return err
}
data, err := user.HandleUserLogin(authUserInfo, l.svcCtx, true, r, w, l.ctx)
if err != nil {
_ = tx.Rollback()
return err
}
marshal, err := json.Marshal(data)
if err != nil {
_ = tx.Rollback()
return err
}
err = websocket.QrcodeWebSocketHandler.SendMessageToClient(clientId, marshal)
if err != nil {
_ = tx.Rollback()
return err
}
}
if err = tx.Commit(); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,112 @@
package oauth
import (
"context"
"encoding/json"
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/contract"
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/messages"
models2 "github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/models"
"github.com/ArtisanCloud/PowerWeChat/v3/src/officialAccount/server/handlers/models"
"net/http"
"schisandra-album-cloud-microservices/app/core/api/common/i18n"
"schisandra-album-cloud-microservices/app/core/api/common/response"
"schisandra-album-cloud-microservices/app/core/api/internal/logic/websocket"
"strings"
"github.com/zeromicro/go-zero/core/logx"
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
)
type WechatOffiaccountCallbackLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
type MessageData struct {
Openid string `json:"openid"`
ClientId string `json:"client_id"`
}
func NewWechatOffiaccountCallbackLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WechatOffiaccountCallbackLogic {
return &WechatOffiaccountCallbackLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *WechatOffiaccountCallbackLogic) WechatOffiaccountCallback(r *http.Request) (*http.Response, error) {
rs, err := l.svcCtx.WechatOfficial.Server.Notify(r, func(event contract.EventInterface) interface{} {
switch event.GetMsgType() {
case models2.CALLBACK_MSG_TYPE_EVENT:
switch event.GetEvent() {
case models.CALLBACK_EVENT_SUBSCRIBE:
msg := models.EventSubscribe{}
err := event.ReadMessage(&msg)
if err != nil {
logx.Error(err.Error())
return "error"
}
key := strings.TrimPrefix(msg.EventKey, "qrscene_")
err = l.SendMessage(msg.FromUserName, key)
if err != nil {
return messages.NewText(i18n.FormatText(l.ctx, "login.loginFailed"))
}
return messages.NewText(i18n.FormatText(l.ctx, "login.loginSuccess"))
case models.CALLBACK_EVENT_UNSUBSCRIBE:
msg := models.EventUnSubscribe{}
err := event.ReadMessage(&msg)
if err != nil {
logx.Error(err.Error())
return "error"
}
return messages.NewText("ok")
case models.CALLBACK_EVENT_SCAN:
msg := models.EventScan{}
err := event.ReadMessage(&msg)
if err != nil {
logx.Error(err.Error())
return "error"
}
err = l.SendMessage(msg.FromUserName, msg.EventKey)
if err != nil {
return messages.NewText(i18n.FormatText(l.ctx, "login.loginFailed"))
}
return messages.NewText(i18n.FormatText(l.ctx, "login.loginSuccess"))
}
case models2.CALLBACK_MSG_TYPE_TEXT:
msg := models.MessageText{}
err := event.ReadMessage(&msg)
if err != nil {
logx.Error(err.Error())
return "error"
}
}
return messages.NewText("ok")
})
if err != nil {
return nil, err
}
return rs, nil
}
// SendMessage 发送消息到客户端
func (l *WechatOffiaccountCallbackLogic) SendMessage(openId string, clientId string) error {
messageData := MessageData{
Openid: openId,
ClientId: clientId,
}
jsonData, err := json.Marshal(response.SuccessWithData(messageData))
if err != nil {
return err
}
err = websocket.QrcodeWebSocketHandler.SendMessageToClient(clientId, jsonData)
if err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,31 @@
package oauth
import (
"context"
"net/http"
"github.com/zeromicro/go-zero/core/logx"
"schisandra-album-cloud-microservices/app/core/api/internal/svc"
)
type WechatOffiaccountCallbackVerifyLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewWechatOffiaccountCallbackVerifyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WechatOffiaccountCallbackVerifyLogic {
return &WechatOffiaccountCallbackVerifyLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *WechatOffiaccountCallbackVerifyLogic) WechatOffiaccountCallbackVerify(r *http.Request) (*http.Response, error) {
rs, err := l.svcCtx.WechatOfficial.Server.VerifyURL(r)
if err != nil {
return nil, err
}
return rs, nil
}