diff --git a/openplatform/context/accessToken.go b/openplatform/context/accessToken.go index 35690d8..9608fdb 100644 --- a/openplatform/context/accessToken.go +++ b/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 } diff --git a/openplatform/officialaccount/js/js.go b/openplatform/officialaccount/js/js.go new file mode 100644 index 0000000..2dd75a8 --- /dev/null +++ b/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×tamp=%d&url=%s", ticketStr, nonceStr, timestamp, uri) + sigStr := util.Signature(str) + + config.AppID = appid + config.NonceStr = nonceStr + config.Timestamp = timestamp + config.Signature = sigStr + return +} diff --git a/openplatform/officialaccount/oauth/oauth.go b/openplatform/officialaccount/oauth/oauth.go new file mode 100644 index 0000000..e8cf1fb --- /dev/null +++ b/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 +} diff --git a/openplatform/officialaccount/officialaccount.go b/openplatform/officialaccount/officialaccount.go index fe4fbbf..882bd88 100644 --- a/openplatform/officialaccount/officialaccount.go +++ b/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