فهرست منبع

增加企业微信网页授权支持

wenzl 7 سال پیش
والد
کامیت
6ac7e1142f
3فایلهای تغییر یافته به همراه171 افزوده شده و 1 حذف شده
  1. 76 0
      context/qy_access_token.go
  2. 0 1
      menu/menu.go
  3. 95 0
      oauth/qy_oauth.go

+ 76 - 0
context/qy_access_token.go

@@ -0,0 +1,76 @@
+package context
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"sync"
+	"time"
+
+	"github.com/silenceper/wechat/util"
+)
+
+const (
+	//qyAccessTokenURL 获取access_token的接口
+	qyAccessTokenURL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s"
+)
+
+//ResQyAccessToken struct
+type ResQyAccessToken struct {
+	util.CommonError
+
+	AccessToken string `json:"access_token"`
+	ExpiresIn   int64  `json:"expires_in"`
+}
+
+//SetQyAccessTokenLock 设置读写锁(一个appID一个读写锁)
+func (ctx *Context) SetQyAccessTokenLock(l *sync.RWMutex) {
+	ctx.accessTokenLock = l
+}
+
+//GetQyAccessToken 获取access_token
+func (ctx *Context) GetQyAccessToken() (accessToken string, err error) {
+	ctx.accessTokenLock.Lock()
+	defer ctx.accessTokenLock.Unlock()
+
+	accessTokenCacheKey := fmt.Sprintf("qy_access_token_%s", ctx.AppID)
+	val := ctx.Cache.Get(accessTokenCacheKey)
+	if val != nil {
+		accessToken = val.(string)
+		return
+	}
+
+	//从微信服务器获取
+	var resQyAccessToken ResQyAccessToken
+	resQyAccessToken, err = ctx.GetQyAccessTokenFromServer()
+	if err != nil {
+		return
+	}
+
+	accessToken = resQyAccessToken.AccessToken
+	return
+}
+
+//GetQyAccessTokenFromServer 强制从微信服务器获取token
+func (ctx *Context) GetQyAccessTokenFromServer() (resQyAccessToken ResQyAccessToken, err error) {
+	log.Printf("GetQyAccessTokenFromServer")
+	url := fmt.Sprintf(qyAccessTokenURL, ctx.AppID, ctx.AppSecret)
+	var body []byte
+	body, err = util.HTTPGet(url)
+	if err != nil {
+		return
+	}
+	err = json.Unmarshal(body, &resQyAccessToken)
+	if err != nil {
+		return
+	}
+	if resQyAccessToken.ErrCode != 0 {
+		err = fmt.Errorf("get qy_access_token error : errcode=%v , errormsg=%v", resQyAccessToken.ErrCode, resQyAccessToken.ErrMsg)
+		return
+	}
+
+	qyAccessTokenCacheKey := fmt.Sprintf("qy_access_token_%s", ctx.AppID)
+	expires := resQyAccessToken.ExpiresIn - 1500
+	err = ctx.Cache.Set(qyAccessTokenCacheKey, resQyAccessToken.AccessToken, time.Duration(expires)*time.Second)
+	return
+}

+ 0 - 1
menu/menu.go

@@ -286,7 +286,6 @@ func (menu *Menu) GetCurrentSelfMenuInfo() (resSelfMenuInfo ResSelfMenuInfo, err
 	if err != nil {
 		return
 	}
-	fmt.Println(string(response))
 	err = json.Unmarshal(response, &resSelfMenuInfo)
 	if err != nil {
 		return

+ 95 - 0
oauth/qy_oauth.go

@@ -0,0 +1,95 @@
+package oauth
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/url"
+
+	"github.com/silenceper/wechat/util"
+)
+
+var (
+	qyRedirectOauthURL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&agentid=%s&state=%s#wechat_redirect"
+	qyUserInfoURL      = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=%s&code=%s"
+	qyUserDetailURL    = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail"
+)
+
+//GetQyRedirectURL 获取企业微信跳转的url地址
+func (oauth *Oauth) GetQyRedirectURL(redirectURI, agentid, scope, state string) (string, error) {
+	//url encode
+	urlStr := url.QueryEscape(redirectURI)
+	return fmt.Sprintf(qyRedirectOauthURL, oauth.AppID, urlStr, scope, agentid, state), nil
+}
+
+//QyUserInfo 用户授权获取到用户信息
+type QyUserInfo struct {
+	util.CommonError
+
+	UserID     string `json:"UserId"`
+	DeviceID   string `json:"DeviceId"`
+	UserTicket string `json:"user_ticket"`
+	ExpiresIn  int64  `json:"expires_in"`
+}
+
+//GetQyUserInfoByCode 根据code获取企业user_info
+func (oauth *Oauth) GetQyUserInfoByCode(code string) (result QyUserInfo, err error) {
+	qyAccessToken, e := oauth.GetQyAccessToken()
+	if e != nil {
+		err = e
+		return
+	}
+	urlStr := fmt.Sprintf(qyUserInfoURL, qyAccessToken, 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("GetQyUserInfoByCode error : errcode=%v , errmsg=%v", result.ErrCode, result.ErrMsg)
+		return
+	}
+	return
+}
+
+//QyUserDetail 到用户详情
+type QyUserDetail struct {
+	util.CommonError
+
+	UserID string `json:"UserId"`
+	Name   string `json:"name"`
+	Mobile string `json:"mobile"`
+	Gender string `json:"gender"`
+	Email  string `json:"email"`
+	Avatar string `json:"avatar"`
+	QrCode string `json:"qr_code"`
+}
+
+//GetQyUserDetailUserTicket 根据user_ticket获取到用户详情
+func (oauth *Oauth) GetQyUserDetailUserTicket(userTicket string) (result QyUserDetail, err error) {
+	var qyAccessToken string
+	qyAccessToken, err = oauth.GetQyAccessToken()
+	if err != nil {
+		return
+	}
+	uri := fmt.Sprintf("%s?access_token=%s", qyUserDetailURL, qyAccessToken)
+	var response []byte
+	response, err = util.PostJSON(uri, map[string]string{
+		"user_ticket": userTicket,
+	})
+	if err != nil {
+		return
+	}
+	err = json.Unmarshal(response, &result)
+	if err != nil {
+		return
+	}
+	if result.ErrCode != 0 {
+		err = fmt.Errorf("GetQyUserDetailUserTicket Error , errcode=%d , errmsg=%s", result.ErrCode, result.ErrMsg)
+		return
+	}
+	return
+}