github.com/chanxuehong/wechat@v0.0.0-20230222024006-36f0325263cd/mp/oauth2/session.go (about) 1 package oauth2 2 3 import ( 4 "encoding/base64" 5 "encoding/json" 6 "fmt" 7 "github.com/chanxuehong/wechat/internal/debug/api" 8 util2 "github.com/chanxuehong/wechat/internal/util" 9 "github.com/chanxuehong/wechat/oauth2" 10 "github.com/chanxuehong/wechat/util" 11 "net/http" 12 ) 13 14 type Session struct { 15 OpenId string `json:"openid"` // 用户唯一标识 16 UnionId string `json:"unionid,omitempty"` // 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回 17 SessionKey string `json:"session_key"` // 会话密钥 18 } 19 20 type SessionInfo struct { 21 OpenId string `json:"openId"` // 用户的唯一标识 22 Nickname string `json:"nickName"` // 用户昵称 23 Gender int `json:"gender"` // 用户的性别, 值为1时是男性, 值为2时是女性, 值为0时是未知 24 Language string `json:"language"` // 用户的语言 25 City string `json:"city"` // 普通用户个人资料填写的城市 26 Province string `json:"province"` // 用户个人资料填写的省份 27 Country string `json:"country"` // 国家, 如中国为CN 28 29 // 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像), 30 // 用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。 31 AvatarUrl string `json:"avatarUrl"` 32 UnionId string `json:"unionId"` // 只有在将小程序绑定到微信开放平台帐号后,才会出现该字段。 33 } 34 35 // GetSession 获取小程序会话 36 func GetSession(Endpoint *Endpoint, code string) (session *Session, err error) { 37 session = &Session{} 38 if err = getSession(session, Endpoint.SessionCodeUrl(code), nil); err != nil { 39 return 40 } 41 return 42 } 43 44 // GetSessionWithClient 获取小程序会话 45 func GetSessionWithClient(Endpoint *Endpoint, code string, httpClient *http.Client) (session *Session, err error) { 46 session = &Session{} 47 if err = getSession(session, Endpoint.SessionCodeUrl(code), httpClient); err != nil { 48 return 49 } 50 return 51 } 52 53 func getSession(session *Session, url string, httpClient *http.Client) (err error) { 54 55 if httpClient == nil { 56 httpClient = util.DefaultHttpClient 57 } 58 59 api.DebugPrintGetRequest(url) 60 61 httpResp, err := httpClient.Get(url) 62 if err != nil { 63 return 64 } 65 defer httpResp.Body.Close() 66 67 if httpResp.StatusCode != http.StatusOK { 68 return fmt.Errorf("http.Status: %s", httpResp.Status) 69 } 70 71 var result struct { 72 oauth2.Error 73 Session 74 } 75 76 if err = api.DecodeJSONHttpResponse(httpResp.Body, &result); err != nil { 77 return 78 } 79 80 if result.ErrCode != oauth2.ErrCodeOK { 81 return &result.Error 82 } 83 84 *session = result.Session 85 86 return 87 } 88 89 // GetSessionInfo 解密小程序会话加密信息 90 func GetSessionInfo(EncryptedData, sessionKey, iv string) (info *SessionInfo, err error) { 91 92 cipherText, err := base64.StdEncoding.DecodeString(EncryptedData) 93 94 aesKey, err := base64.StdEncoding.DecodeString(sessionKey) 95 aesIv, err := base64.StdEncoding.DecodeString(iv) 96 97 if err != nil { 98 return 99 } 100 101 raw, err := util2.AESDecryptData(cipherText, aesKey, aesIv) 102 103 if err != nil { 104 return 105 } 106 107 if err = json.Unmarshal(raw, &info); err != nil { 108 return 109 } 110 return 111 }