Ver Fonte

fix: platform wx oauth and js config issue. (#302)

* fix: platform wx oauth and js config issue.

fix silenceper/wechat#301.

* fix: platform query auth code error not detected.

* feat: migrate platform oauth and js api.

* fix: func name
NaRro há 5 anos atrás
pai
commit
6f2bd492fc

+ 5 - 1
openplatform/context/accessToken.go

@@ -128,13 +128,17 @@ func (ctx *Context) QueryAuthCode(authCode string) (*AuthBaseInfo, error) {
 	}
 
 	var ret struct {
+		util.CommonError
 		Info *AuthBaseInfo `json:"authorization_info"`
 	}
 
 	if err := json.Unmarshal(body, &ret); err != nil {
 		return nil, err
 	}
-
+	if ret.ErrCode != 0 {
+		err = fmt.Errorf("QueryAuthCode error : errcode=%v , errmsg=%v", ret.ErrCode, ret.ErrMsg)
+		return nil, err
+	}
 	return ret.Info, nil
 }
 

+ 57 - 0
openplatform/officialaccount/js/js.go

@@ -0,0 +1,57 @@
+package js
+
+import (
+	"fmt"
+
+	"github.com/silenceper/wechat/v2/credential"
+	"github.com/silenceper/wechat/v2/officialaccount/context"
+	officialJs "github.com/silenceper/wechat/v2/officialaccount/js"
+	"github.com/silenceper/wechat/v2/util"
+)
+
+// Js wx jssdk
+type Js struct {
+	*context.Context
+	credential.JsTicketHandle
+}
+
+//NewJs init
+func NewJs(context *context.Context) *Js {
+	js := new(Js)
+	js.Context = context
+	jsTicketHandle := credential.NewDefaultJsTicket(context.AppID, credential.CacheKeyOfficialAccountPrefix, context.Cache)
+	js.SetJsTicketHandle(jsTicketHandle)
+	return js
+}
+
+//SetJsTicketHandle 自定义js ticket取值方式
+func (js *Js) SetJsTicketHandle(ticketHandle credential.JsTicketHandle) {
+	js.JsTicketHandle = ticketHandle
+}
+
+//GetConfig 第三方平台 - 获取jssdk需要的配置参数
+//uri 为当前网页地址
+func (js *Js) GetConfig(uri, appid string) (config *officialJs.Config, err error) {
+	config = new(officialJs.Config)
+	var accessToken string
+	accessToken, err = js.GetAccessToken()
+	if err != nil {
+		return
+	}
+	var ticketStr string
+	ticketStr, err = js.GetTicket(accessToken)
+	if err != nil {
+		return
+	}
+
+	nonceStr := util.RandomStr(16)
+	timestamp := util.GetCurrTS()
+	str := fmt.Sprintf("jsapi_ticket=%s&noncestr=%s&timestamp=%d&url=%s", ticketStr, nonceStr, timestamp, uri)
+	sigStr := util.Signature(str)
+
+	config.AppID = appid
+	config.NonceStr = nonceStr
+	config.Timestamp = timestamp
+	config.Signature = sigStr
+	return
+}

+ 65 - 0
openplatform/officialaccount/oauth/oauth.go

@@ -0,0 +1,65 @@
+package oauth
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"net/url"
+
+	"github.com/silenceper/wechat/v2/officialaccount/context"
+	officialOauth "github.com/silenceper/wechat/v2/officialaccount/oauth"
+	"github.com/silenceper/wechat/v2/util"
+)
+
+const (
+	platformRedirectOauthURL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect"
+	platformAccessTokenURL   = "https://api.weixin.qq.com/sns/oauth2/component/access_token?appid=%s&code=%s&grant_type=authorization_code&component_appid=%s&component_access_token=%s"
+)
+
+// Oauth 平台代发起oauth2网页授权
+type Oauth struct {
+	*context.Context
+}
+
+// NewOauth 实例化平台代发起oauth2网页授权
+func NewOauth(context *context.Context) *Oauth {
+	auth := new(Oauth)
+	auth.Context = context
+	return auth
+}
+
+//GetRedirectURL 第三方平台 - 获取跳转的url地址
+func (oauth *Oauth) GetRedirectURL(redirectURI, scope, state, appID string) (string, error) {
+	//url encode
+	urlStr := url.QueryEscape(redirectURI)
+	return fmt.Sprintf(platformRedirectOauthURL, appID, urlStr, scope, state, oauth.AppID), nil
+}
+
+//Redirect 第三方平台 - 跳转到网页授权
+func (oauth *Oauth) Redirect(writer http.ResponseWriter, req *http.Request, redirectURI, scope, state, appID string) error {
+	location, err := oauth.GetRedirectURL(redirectURI, scope, state, appID)
+	if err != nil {
+		return err
+	}
+	http.Redirect(writer, req, location, http.StatusFound)
+	return nil
+}
+
+// GetUserAccessToken 第三方平台 - 通过网页授权的code 换取access_token(区别于context中的access_token)
+func (oauth *Oauth) GetUserAccessToken(code, appID, componentAccessToken string) (result officialOauth.ResAccessToken, err error) {
+	urlStr := fmt.Sprintf(platformAccessTokenURL, appID, code, oauth.AppID, componentAccessToken)
+	var response []byte
+	response, err = util.HTTPGet(urlStr)
+	if err != nil {
+		return
+	}
+	err = json.Unmarshal(response, &result)
+	if err != nil {
+		return
+	}
+	if result.ErrCode != 0 {
+		err = fmt.Errorf("GetUserAccessToken error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
+		return
+	}
+	return
+}

+ 12 - 0
openplatform/officialaccount/officialaccount.go

@@ -5,6 +5,8 @@ import (
 	"github.com/silenceper/wechat/v2/officialaccount"
 	offConfig "github.com/silenceper/wechat/v2/officialaccount/config"
 	opContext "github.com/silenceper/wechat/v2/openplatform/context"
+	"github.com/silenceper/wechat/v2/openplatform/officialaccount/js"
+	"github.com/silenceper/wechat/v2/openplatform/officialaccount/oauth"
 )
 
 //OfficialAccount 代公众号实现业务
@@ -28,6 +30,16 @@ func NewOfficialAccount(opCtx *opContext.Context, appID string) *OfficialAccount
 	return &OfficialAccount{appID: appID, OfficialAccount: officialAccount}
 }
 
+// PlatformOauth 平台代发起oauth2网页授权
+func (officialAccount *OfficialAccount) PlatformOauth() *oauth.Oauth {
+	return oauth.NewOauth(officialAccount.GetContext())
+}
+
+// PlatformJs 平台代获取js-sdk配置
+func (officialAccount *OfficialAccount) PlatformJs() *js.Js {
+	return js.NewJs(officialAccount.GetContext())
+}
+
 //DefaultAuthrAccessToken 默认获取授权ak的方法
 type DefaultAuthrAccessToken struct {
 	opCtx *opContext.Context