216 lines
6.2 KiB
Go
216 lines
6.2 KiB
Go
package client
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"net/http"
|
||
)
|
||
|
||
const (
|
||
UserAppID = ""
|
||
UserSecret = ""
|
||
DriverAppID = ""
|
||
DriverSecret = ""
|
||
Code2SessionAppURL = "https://api.weixin.qq.com/sns/oauth2/access_token"
|
||
UserInfoAppURL = "https://api.weixin.qq.com/sns/userinfo"
|
||
|
||
Code2SessionJsURL = "https://api.weixin.qq.com/sns/jscode2session"
|
||
|
||
SendMessageURL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN"
|
||
GetAccessTokenURL = "https://api.weixin.qq.com/cgi-bin/token"
|
||
)
|
||
|
||
func WeChatNewAuthJsReqMap(code string) map[string]string {
|
||
return map[string]string{
|
||
"appid": UserAppID,
|
||
"secret": UserSecret,
|
||
"js_code": code,
|
||
"grant_type": "authorization_code"}
|
||
}
|
||
|
||
func WeChatNewAuthAppReqMap(code string) map[string]string {
|
||
return map[string]string{
|
||
"appid": UserAppID,
|
||
"secret": UserSecret,
|
||
"code": code,
|
||
"grant_type": "authorization_code"}
|
||
}
|
||
|
||
func WeChatGetAccessTokenReq(_type int) map[string]string {
|
||
switch _type {
|
||
case 1: // 用户
|
||
return map[string]string{
|
||
"grant_type": "client_credential",
|
||
"appid": UserAppID,
|
||
"secret": UserSecret,
|
||
}
|
||
case 2: // 其他
|
||
return map[string]string{
|
||
"grant_type": "client_credential",
|
||
"appid": DriverAppID,
|
||
"secret": DriverSecret,
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// 小程序换取token的返回
|
||
type WeChatLoginJsRes struct {
|
||
SessionKey string `json:"session_key"`
|
||
UnionID string `json:"unionid"`
|
||
OpenID string `json:"openid"`
|
||
ErrCode int32 `json:"errcode"`
|
||
ErrMsg string `json:"errmsg"`
|
||
}
|
||
|
||
// APP换取token的返回
|
||
type WeChatLoginAppRes struct {
|
||
AccessToken string `json:"access_token"` // 接口调用凭证
|
||
ExpiresIn int32 `json:"expires_in"` // access_token 接口调用凭证超时时间,单位(秒)
|
||
RefreshToken string `json:"refresh_token"` // 用户刷新 access_token
|
||
UnionID string `json:"unionid"` // 用户统一标识。针对一个微信开放平台账号下的应用,同一用户的 unionid 是唯一的
|
||
OpenID string `json:"openid"` // 授权用户唯一标识
|
||
Scope string `json:"scope"` // 用户授权的作用域,使用逗号(,)分隔
|
||
ErrCode int32 `json:"errcode"`
|
||
ErrMsg string `json:"errmsg"`
|
||
}
|
||
|
||
// APP获取用户信息
|
||
type WeChatUserInfoAppRes struct {
|
||
UnionID string `json:"unionid"` // 用户统一标识。针对一个微信开放平台账号下的应用,同一用户的 unionid 是唯一的
|
||
OpenID string `json:"openid"` // 授权用户唯一标识
|
||
Nickname string `json:"nickname"` // 普通用户昵称
|
||
Sex int32 `json:"sex"` // 普通用户性别,1 为男性,2 为女性
|
||
Province string `json:"province"` // 普通用户个人资料填写的省份
|
||
City string `json:"city"` // 普通用户个人资料填写的城市
|
||
Country string `json:"country"` // 国家,如中国为 CN
|
||
Avatar string `json:"headimgurl"` // 用户头像,最后一个数值代表正方形头像大小(有 0、46、64、96、132 数值可选,0 代表 640*640 正方形头像),用户没有头像时该项为空
|
||
ErrCode int32 `json:"errcode"`
|
||
ErrMsg string `json:"errmsg"`
|
||
}
|
||
|
||
// 换取token所用的请求
|
||
func WeChatNewAuthReqMapUser(code string) map[string]string {
|
||
return map[string]string{
|
||
"appid": UserAppID,
|
||
"secret": UserSecret,
|
||
"js_code": code,
|
||
"grant_type": "authorization_code"}
|
||
}
|
||
|
||
// 小程序换取token的请求
|
||
func WeChatCode2JsSession(headers map[string]string, params map[string]string) (wxLoginBody WeChatLoginJsRes, e error) {
|
||
var (
|
||
client = NewClient()
|
||
resp *http.Response
|
||
res []byte
|
||
)
|
||
req, _ := http.NewRequest(http.MethodGet, Code2SessionJsURL, nil)
|
||
for k, v := range headers {
|
||
req.Header.Add(k, v)
|
||
}
|
||
q := req.URL.Query()
|
||
for k, v := range params {
|
||
q.Add(k, v)
|
||
}
|
||
req.URL.RawQuery = q.Encode()
|
||
if resp, e = client.Do(req); e != nil {
|
||
return
|
||
}
|
||
defer func(body io.ReadCloser) {
|
||
_ = body.Close()
|
||
}(resp.Body)
|
||
if res, e = io.ReadAll(resp.Body); e != nil {
|
||
return
|
||
}
|
||
if !success(resp.StatusCode) {
|
||
e = fmt.Errorf("status code error: %s", resp.Status)
|
||
}
|
||
if e = json.Unmarshal(res, &wxLoginBody); e != nil {
|
||
return
|
||
}
|
||
if wxLoginBody.ErrCode != 0 {
|
||
e = fmt.Errorf("获取微信登录凭证错误,错误码: %d 错误信息:%s", wxLoginBody.ErrCode, wxLoginBody.ErrMsg)
|
||
return
|
||
}
|
||
return
|
||
}
|
||
|
||
// APP换取token的请求
|
||
func WeChatCode2AppToken(headers map[string]string, params map[string]string) (wxLoginBody WeChatLoginAppRes, e error) {
|
||
var (
|
||
client = NewClient()
|
||
resp *http.Response
|
||
res []byte
|
||
)
|
||
req, _ := http.NewRequest(http.MethodGet, Code2SessionAppURL, nil)
|
||
for k, v := range headers {
|
||
req.Header.Add(k, v)
|
||
}
|
||
q := req.URL.Query()
|
||
for k, v := range params {
|
||
q.Add(k, v)
|
||
}
|
||
req.URL.RawQuery = q.Encode()
|
||
if resp, e = client.Do(req); e != nil {
|
||
return
|
||
}
|
||
defer func(body io.ReadCloser) {
|
||
_ = body.Close()
|
||
}(resp.Body)
|
||
if res, e = io.ReadAll(resp.Body); e != nil {
|
||
return
|
||
}
|
||
if !success(resp.StatusCode) {
|
||
e = fmt.Errorf("status code error: %s", resp.Status)
|
||
}
|
||
if e = json.Unmarshal(res, &wxLoginBody); e != nil {
|
||
return
|
||
}
|
||
if wxLoginBody.ErrCode != 0 {
|
||
e = fmt.Errorf("获取微信登录凭证错误,错误码: %d 错误信息:%s", wxLoginBody.ErrCode, wxLoginBody.ErrMsg)
|
||
return
|
||
}
|
||
return
|
||
}
|
||
|
||
// APP获取用户信息
|
||
func WeChatUserInfoApp(token, openId string) (wxUserInfoBody WeChatUserInfoAppRes, e error) {
|
||
var (
|
||
client = NewClient()
|
||
resp *http.Response
|
||
res []byte
|
||
)
|
||
req, _ := http.NewRequest(http.MethodGet, UserInfoAppURL, nil)
|
||
|
||
q := req.URL.Query()
|
||
q.Add("access_token", token)
|
||
q.Add("openid", openId)
|
||
req.URL.RawQuery = q.Encode()
|
||
if resp, e = client.Do(req); e != nil {
|
||
return
|
||
}
|
||
defer func(body io.ReadCloser) {
|
||
_ = body.Close()
|
||
}(resp.Body)
|
||
if res, e = io.ReadAll(resp.Body); e != nil {
|
||
return
|
||
}
|
||
if !success(resp.StatusCode) {
|
||
e = fmt.Errorf("status code error: %s", resp.Status)
|
||
}
|
||
if e = json.Unmarshal(res, &wxUserInfoBody); e != nil {
|
||
return
|
||
}
|
||
if wxUserInfoBody.ErrCode != 0 {
|
||
e = fmt.Errorf("获取微信登录凭证错误,错误码: %d 错误信息:%s", wxUserInfoBody.ErrCode, wxUserInfoBody.ErrMsg)
|
||
return
|
||
}
|
||
return
|
||
}
|
||
|
||
func success(code int) bool {
|
||
return code >= 200 && code < 400
|
||
}
|