| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- package oauth
- import (
- "encoding/json"
- "fmt"
- "net/http"
- "net/url"
- "github.com/silenceper/wechat/context"
- "github.com/silenceper/wechat/util"
- )
- const (
- redirectOauthURL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect"
- accessTokenURL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"
- refreshAccessTokenURL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s"
- userInfoURL = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN"
- checkAccessTokenURL = "https://api.weixin.qq.com/sns/auth?access_token=%s&openid=%s"
- )
- //Oauth 保存用户授权信息
- type Oauth struct {
- *context.Context
- }
- //NewOauth 实例化授权信息
- func NewOauth(context *context.Context) *Oauth {
- auth := new(Oauth)
- auth.Context = context
- return auth
- }
- //GetRedirectURL 获取跳转的url地址
- func (oauth *Oauth) GetRedirectURL(redirectURI, scope, state string) (string, error) {
- //url encode
- urlStr := url.QueryEscape(redirectURI)
- return fmt.Sprintf(redirectOauthURL, oauth.AppID, urlStr, scope, state), nil
- }
- //Redirect 跳转到网页授权
- func (oauth *Oauth) Redirect(redirectURI, scope, state string) error {
- location, err := oauth.GetRedirectURL(redirectURI, scope, state)
- if err != nil {
- return err
- }
- http.Redirect(oauth.Writer, oauth.Request, location, 302)
- return nil
- }
- // ResAccessToken 获取用户授权access_token的返回结果
- type ResAccessToken struct {
- util.CommonError
- AccessToken string `json:"access_token"`
- ExpiresIn int64 `json:"expires_in"`
- RefreshToken string `json:"refresh_token"`
- OpenID string `json:"openid"`
- Scope string `json:"scope"`
- }
- // GetUserAccessToken 通过网页授权的code 换取access_token(区别于context中的access_token)
- func (oauth *Oauth) GetUserAccessToken(code string) (result ResAccessToken, err error) {
- urlStr := fmt.Sprintf(accessTokenURL, oauth.AppID, oauth.AppSecret, code)
- var response []byte
- response, err = util.HTTPGet(urlStr)
- if err != nil {
- return
- }
- err = json.Unmarshal(response, &result)
- if err != nil {
- return
- }
- if result.ErrCode != 0 {
- err = fmt.Errorf("GetUserAccessToken error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
- return
- }
- return
- }
- //RefreshAccessToken 刷新access_token
- func (oauth *Oauth) RefreshAccessToken(refreshToken string) (result ResAccessToken, err error) {
- urlStr := fmt.Sprintf(refreshAccessTokenURL, oauth.AppID, refreshToken)
- var response []byte
- response, err = util.HTTPGet(urlStr)
- if err != nil {
- return
- }
- err = json.Unmarshal(response, &result)
- if err != nil {
- return
- }
- if result.ErrCode != 0 {
- err = fmt.Errorf("GetUserAccessToken error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
- return
- }
- return
- }
- //CheckAccessToken 检验access_token是否有效
- func (oauth *Oauth) CheckAccessToken(accessToken, openID string) (b bool, err error) {
- urlStr := fmt.Sprintf(checkAccessTokenURL, accessToken, openID)
- var response []byte
- response, err = util.HTTPGet(urlStr)
- if err != nil {
- return
- }
- var result util.CommonError
- err = json.Unmarshal(response, &result)
- if err != nil {
- return
- }
- if result.ErrCode != 0 {
- b = false
- return
- }
- b = true
- return
- }
- //UserInfo 用户授权获取到用户信息
- type UserInfo struct {
- util.CommonError
- OpenID string `json:"openid"`
- Nickname string `json:"nickname"`
- Sex int32 `json:"sex"`
- Province string `json:"province"`
- City string `json:"city"`
- Country string `json:"country"`
- HeadImgURL string `json:"headimgurl"`
- Privilege []string `json:"privilege"`
- Unionid string `json:"unionid"`
- }
- //GetUserInfo 如果scope为 snsapi_userinfo 则可以通过此方法获取到用户基本信息
- func (oauth *Oauth) GetUserInfo(accessToken, openID string) (result UserInfo, err error) {
- urlStr := fmt.Sprintf(userInfoURL, accessToken, openID)
- var response []byte
- response, err = util.HTTPGet(urlStr)
- if err != nil {
- return
- }
- err = json.Unmarshal(response, &result)
- if err != nil {
- return
- }
- if result.ErrCode != 0 {
- err = fmt.Errorf("GetUserInfo error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
- return
- }
- return
- }
|