138 lines
2.7 KiB
Go
138 lines
2.7 KiB
Go
|
package oauth2
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"net/url"
|
||
|
|
||
|
"git.esin.io/lab/weixin/clientapi/request"
|
||
|
)
|
||
|
|
||
|
type Oauth2Client struct {
|
||
|
appId string
|
||
|
appSecret string
|
||
|
}
|
||
|
|
||
|
type GetCodeURLRequest struct {
|
||
|
RedirectURL, State, Scope string
|
||
|
}
|
||
|
|
||
|
func (c Oauth2Client) GetCodeURL(redirectURL, state, scope string) string {
|
||
|
endpoint := url.URL{
|
||
|
Scheme: "https",
|
||
|
Host: "open.weixin.qq.com",
|
||
|
Path: "/connect/oauth2/authorize",
|
||
|
RawQuery: url.Values{
|
||
|
"appid": {c.appId},
|
||
|
"redirect_uri": {redirectURL},
|
||
|
"response_type": {"code"},
|
||
|
"scope": {scope},
|
||
|
"state": {state},
|
||
|
}.Encode(),
|
||
|
Fragment: "wechat_redirect",
|
||
|
}
|
||
|
return endpoint.String()
|
||
|
}
|
||
|
|
||
|
func (c Oauth2Client) ExchangeToken(ctx context.Context, code string) (*Token, error) {
|
||
|
req := request.New(
|
||
|
"/sns/oauth2/access_token",
|
||
|
url.Values{
|
||
|
"grant_type": {"authorization_code"},
|
||
|
"appid": {c.appId},
|
||
|
"secret": {c.appSecret},
|
||
|
"code": {code},
|
||
|
})
|
||
|
var resp Token
|
||
|
if err := req.Get(ctx, &resp); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
if err := resp.Err(); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return &resp, nil
|
||
|
}
|
||
|
|
||
|
func (c Oauth2Client) GetUserinfo(ctx context.Context, accessToken, openid string) (*Userinfo, error) {
|
||
|
req := request.New(
|
||
|
"/sns/userinfo",
|
||
|
url.Values{
|
||
|
"access_token": {accessToken},
|
||
|
"openid": {openid},
|
||
|
"lang": {"zh_CN"},
|
||
|
},
|
||
|
)
|
||
|
var resp Userinfo
|
||
|
if err := req.Get(ctx, &resp); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
if err := resp.Err(); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return &resp, nil
|
||
|
}
|
||
|
|
||
|
func (c Oauth2Client) RefreshToken(ctx context.Context, refreshToken, openid string) (*Token, error) {
|
||
|
req := request.New(
|
||
|
"/sns/oauth2/refresh_token",
|
||
|
url.Values{
|
||
|
"grant_type": {"refresh_token"},
|
||
|
"appid": {c.appId},
|
||
|
"refresh_token": {refreshToken},
|
||
|
},
|
||
|
)
|
||
|
|
||
|
var resp Token
|
||
|
if err := req.Get(ctx, &resp); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
if err := resp.Err(); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return &resp, nil
|
||
|
}
|
||
|
|
||
|
func (c Oauth2Client) ValidateToken(ctx context.Context, accessToken, openid string) error {
|
||
|
req := request.New(
|
||
|
"/sns/auth",
|
||
|
url.Values{
|
||
|
"access_token": {accessToken},
|
||
|
"openid": {openid},
|
||
|
},
|
||
|
)
|
||
|
|
||
|
var resp request.Error
|
||
|
if err := req.Get(ctx, &resp); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if err := resp.Err(); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (c Oauth2Client) GetClientCredential(ctx context.Context) (*ClientCredential, error) {
|
||
|
req := request.New(
|
||
|
"/cgi-bin/token",
|
||
|
url.Values{
|
||
|
"grant_type": {"client_credential"},
|
||
|
"appid": {c.appId},
|
||
|
"secret": {c.appSecret},
|
||
|
},
|
||
|
)
|
||
|
|
||
|
var resp ClientCredential
|
||
|
if err := req.Get(ctx, &resp); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
if err := resp.Err(); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return &resp, nil
|
||
|
}
|