feat: complete auth

This commit is contained in:
Rogee
2024-11-27 20:58:41 +08:00
parent e4b9cc5f26
commit 301879ca39
10 changed files with 380 additions and 54 deletions

View File

@@ -3,6 +3,7 @@ package wechat
import (
"crypto/sha1"
"encoding/hex"
"net/url"
"sort"
"strings"
@@ -17,6 +18,17 @@ var DefaultClient = req.
SetBaseURL(BaseURL).
SetCommonHeader("Content-Type", "application/json")
const (
ScopeBase = "snsapi_base"
ScopeUserInfo = "snsapi_userinfo"
)
type AuthScope string
func (s AuthScope) String() string {
return string(s)
}
type Client struct {
client *req.Client
@@ -38,7 +50,7 @@ func New(options ...Options) *Client {
return we
}
func (we *Client) VerifyServer(signature, timestamp, nonce string) error {
func (we *Client) Verify(signature, timestamp, nonce string) error {
params := []string{signature, timestamp, nonce, we.token}
sort.Strings(params)
str := strings.Join(params, "")
@@ -52,11 +64,20 @@ func (we *Client) VerifyServer(signature, timestamp, nonce string) error {
return nil
}
func (we *Client) wrapParams(params map[string]string) map[string]string {
if params == nil {
params = make(map[string]string)
}
params["appid"] = we.appID
params["secret"] = we.appSecret
return params
}
func (we *Client) GetAccessToken() (*AccessTokenResponse, error) {
params := map[string]string{
"grant_type": "client_credential",
"appid": we.appID,
"secret": we.appSecret,
}
var data AccessTokenResponse
@@ -67,3 +88,95 @@ func (we *Client) GetAccessToken() (*AccessTokenResponse, error) {
return &data, nil
}
// ScopeAuthorizeURL
func (we *Client) ScopeAuthorizeURL(opts ...ScopeAuthorizeURLOptions) (*url.URL, error) {
params := url.Values{}
params.Add("appid", we.appID)
params.Add("response_type", "code")
for _, opt := range opts {
opt(params)
}
if params.Get("scope") == "" {
params.Add("scope", ScopeBase)
}
u, err := url.Parse("https://open.weixin.qq.com/connect/oauth2/authorize")
if err != nil {
return nil, errors.Wrap(err, "parse url failed")
}
u.Fragment = "wechat_redirect"
u.RawQuery = url.Values(params).Encode()
return u, nil
}
type AuthorizeAccessToken struct {
AccessToken string `json:"access_token"`
ExpiresIn int64 `json:"expires_in"`
IsSnapshotuser int64 `json:"is_snapshotuser"`
Openid string `json:"openid"`
RefreshToken string `json:"refresh_token"`
Scope string `json:"scope"`
Unionid string `json:"unionid"`
}
func (we *Client) AuthorizeCode2Token(code string) (*AuthorizeAccessToken, error) {
params := we.wrapParams(map[string]string{
"code": code,
"grant_type": "authorization_code",
})
var data AuthorizeAccessToken
_, err := we.client.R().SetSuccessResult(&data).SetQueryParams(params).Get("/sns/oauth2/access_token")
if err != nil {
return nil, errors.Wrap(err, "call /sns/oauth2/access_token failed")
}
return &data, nil
}
func (we *Client) AuthorizeRefreshAccessToken(accessToken string) (*AuthorizeAccessToken, error) {
params := we.wrapParams(map[string]string{
"refresh_token": accessToken,
"grant_type": "refresh_token",
})
var data AuthorizeAccessToken
_, err := we.client.R().SetSuccessResult(&data).SetQueryParams(params).Get("/sns/oauth2/refresh_token")
if err != nil {
return nil, errors.Wrap(err, "call /sns/oauth2/refresh_token failed")
}
return &data, nil
}
type AuthorizeUserInfo struct {
City string `json:"city"`
Country string `json:"country"`
Headimgurl string `json:"headimgurl"`
Nickname string `json:"nickname"`
Openid string `json:"openid"`
Privilege []string `json:"privilege"`
Province string `json:"province"`
Sex int64 `json:"sex"`
Unionid string `json:"unionid"`
}
func (we *Client) AuthorizeUserInfo(accessToken, openID string) (*AuthorizeUserInfo, error) {
params := (map[string]string{
"access_token": accessToken,
"openid": openID,
})
var data AuthorizeUserInfo
_, err := we.client.R().SetSuccessResult(&data).SetQueryParams(params).Get("/sns/userinfo")
if err != nil {
return nil, errors.Wrap(err, "call /sns/userinfo failed")
}
return &data, nil
}