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 }