feat: fix bug in WeChat OA login (#2674)

* fix: fix the problem of Wechat Official Account login

* fix: fix code format problem

* fix: add error display and fix the code format problem

* fix: i18n problem and code format
This commit is contained in:
dacongda
2024-02-05 21:38:12 +08:00
committed by GitHub
parent 7d0eae230e
commit 167c1b0f1b
32 changed files with 266 additions and 101 deletions

View File

@ -38,7 +38,7 @@ import (
)
var (
wechatScanType string
wechatCacheMap map[string]idp.WechatCacheMapValue
lock sync.RWMutex
)
@ -919,49 +919,115 @@ func (c *ApiController) HandleSamlLogin() {
// @Tag System API
// @Title HandleOfficialAccountEvent
// @router /webhook [POST]
// @Success 200 {object} object.Userinfo The Response object
// @Success 200 {object} controllers.Response The Response object
func (c *ApiController) HandleOfficialAccountEvent() {
if c.Ctx.Request.Method == "GET" {
s := c.Ctx.Request.FormValue("echostr")
echostr, _ := strconv.Atoi(s)
c.SetData(echostr)
c.ServeJSON()
return
}
respBytes, err := io.ReadAll(c.Ctx.Request.Body)
if err != nil {
c.ResponseError(err.Error())
return
}
signature := c.Input().Get("signature")
timestamp := c.Input().Get("timestamp")
nonce := c.Input().Get("nonce")
var data struct {
MsgType string `xml:"MsgType"`
Event string `xml:"Event"`
EventKey string `xml:"EventKey"`
MsgType string `xml:"MsgType"`
Event string `xml:"Event"`
EventKey string `xml:"EventKey"`
FromUserName string `xml:"FromUserName"`
Ticket string `xml:"Ticket"`
}
err = xml.Unmarshal(respBytes, &data)
if err != nil {
c.ResponseError(err.Error())
return
}
if strings.ToUpper(data.Event) != "SCAN" && strings.ToUpper(data.Event) != "SUBSCRIBE" {
c.Ctx.WriteString("")
return
}
if data.Ticket == "" {
c.ResponseError(err.Error())
return
}
providerId := data.EventKey
provider, err := object.GetProvider(providerId)
if err != nil {
c.ResponseError(err.Error())
return
}
if data.Ticket == "" {
c.ResponseError("empty ticket")
return
}
if !idp.VerifyWechatSignature(provider.Content, nonce, timestamp, signature) {
c.ResponseError("invalid signature")
return
}
lock.Lock()
defer lock.Unlock()
if data.EventKey != "" {
wechatScanType = data.Event
c.Ctx.WriteString("")
if wechatCacheMap == nil {
wechatCacheMap = make(map[string]idp.WechatCacheMapValue)
}
wechatCacheMap[data.Ticket] = idp.WechatCacheMapValue{
IsScanned: true,
WechatOpenId: data.FromUserName,
}
lock.Unlock()
c.Ctx.WriteString("")
}
// GetWebhookEventType ...
// @Tag System API
// @Title GetWebhookEventType
// @router /get-webhook-event [GET]
// @Success 200 {object} object.Userinfo The Response object
// @Param ticket query string true "The eventId of QRCode"
// @Success 200 {object} controllers.Response The Response object
func (c *ApiController) GetWebhookEventType() {
lock.Lock()
defer lock.Unlock()
resp := &Response{
Status: "ok",
Msg: "",
Data: wechatScanType,
ticket := c.Input().Get("ticket")
lock.RLock()
wechatMsg, ok := wechatCacheMap[ticket]
lock.RUnlock()
if !ok {
c.ResponseError("ticket not found")
return
}
c.Data["json"] = resp
wechatScanType = ""
c.ServeJSON()
lock.Lock()
delete(wechatCacheMap, ticket)
lock.Unlock()
c.ResponseOk("SCAN", wechatMsg.IsScanned)
}
// GetQRCode
// @Tag System API
// @Title GetWechatQRCode
// @router /get-qrcode [GET]
// @Param id query string true "The id ( owner/name ) of provider"
// @Success 200 {object} controllers.Response The Response object
func (c *ApiController) GetQRCode() {
providerId := c.Input().Get("id")
provider, err := object.GetProvider(providerId)
if err != nil {
c.ResponseError(err.Error())
return
}
code, ticket, err := idp.GetWechatOfficialAccountQRCode(provider.ClientId2, provider.ClientSecret2, providerId)
if err != nil {
c.ResponseError(err.Error())
return
}
c.ResponseOk(code, ticket)
}
// GetCaptchaStatus