60 lines
1.3 KiB
Go
60 lines
1.3 KiB
Go
|
|
package utils
|
||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/json"
|
||
|
|
"fmt"
|
||
|
|
"io"
|
||
|
|
"net/http"
|
||
|
|
"net/url"
|
||
|
|
"os"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
type WxSessionResult struct {
|
||
|
|
OpenID string `json:"openid"`
|
||
|
|
SessionKey string `json:"session_key"`
|
||
|
|
UnionID string `json:"unionid"`
|
||
|
|
ErrCode int `json:"errcode"`
|
||
|
|
ErrMsg string `json:"errmsg"`
|
||
|
|
}
|
||
|
|
|
||
|
|
// Code2Session exchanges mini-program login code for openid.
|
||
|
|
func Code2Session(code string) (*WxSessionResult, error) {
|
||
|
|
appID := os.Getenv("WECHAT_APP_ID")
|
||
|
|
secret := os.Getenv("WECHAT_APP_SECRET")
|
||
|
|
if appID == "" {
|
||
|
|
appID = "wx67e73fb3c9882dfc"
|
||
|
|
}
|
||
|
|
if secret == "" {
|
||
|
|
return nil, fmt.Errorf("WECHAT_APP_SECRET is not configured")
|
||
|
|
}
|
||
|
|
|
||
|
|
q := url.Values{}
|
||
|
|
q.Set("appid", appID)
|
||
|
|
q.Set("secret", secret)
|
||
|
|
q.Set("js_code", code)
|
||
|
|
q.Set("grant_type", "authorization_code")
|
||
|
|
|
||
|
|
endpoint := "https://api.weixin.qq.com/sns/jscode2session?" + q.Encode()
|
||
|
|
client := &http.Client{Timeout: 10 * time.Second}
|
||
|
|
resp, err := client.Get(endpoint)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
defer resp.Body.Close()
|
||
|
|
|
||
|
|
body, err := io.ReadAll(resp.Body)
|
||
|
|
if err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
|
||
|
|
var result WxSessionResult
|
||
|
|
if err := json.Unmarshal(body, &result); err != nil {
|
||
|
|
return nil, err
|
||
|
|
}
|
||
|
|
if result.ErrCode != 0 || result.OpenID == "" {
|
||
|
|
return nil, fmt.Errorf("jscode2session failed: %d %s", result.ErrCode, result.ErrMsg)
|
||
|
|
}
|
||
|
|
return &result, nil
|
||
|
|
}
|