1
0
mirror of https://github.com/silenceper/wechat.git synced 2026-02-04 12:52:27 +08:00

实现access_token获取

This commit is contained in:
wenzl
2016-09-11 13:16:15 +08:00
parent 33f2b2ef60
commit d9075933c1
7 changed files with 195 additions and 4 deletions

11
cache/cache.go vendored Normal file
View File

@@ -0,0 +1,11 @@
package cache
import "time"
//Cache interface
type Cache interface {
Get(key string) interface{}
Set(key string, val interface{}, timeput time.Duration) error
IsExist(key string) bool
Delete(key string) error
}

51
cache/memcache.go vendored Normal file
View File

@@ -0,0 +1,51 @@
package cache
import (
"errors"
"time"
"github.com/bradfitz/gomemcache/memcache"
)
//Memcache struct contains *memcache.Client
type Memcache struct {
conn *memcache.Client
}
//NewMemcache create new memcache
func NewMemcache(server ...string) *Memcache {
mc := memcache.New(server...)
return &Memcache{mc}
}
//Get return cached value
func (mem *Memcache) Get(key string) interface{} {
if item, err := mem.conn.Get(key); err == nil {
return string(item.Value)
}
return nil
}
// IsExist check value exists in memcache.
func (mem *Memcache) IsExist(key string) bool {
_, err := mem.conn.Get(key)
if err != nil {
return false
}
return true
}
//Set cached value with key and expire time.
func (mem *Memcache) Set(key string, val interface{}, timeout time.Duration) error {
v, ok := val.(string)
if !ok {
return errors.New("val must string")
}
item := &memcache.Item{Key: key, Value: []byte(v), Expiration: int32(timeout / time.Second)}
return mem.conn.Set(item)
}
//Delete delete value in memcache.
func (mem *Memcache) Delete(key string) error {
return mem.conn.Delete(key)
}

28
cache/memcache_test.go vendored Normal file
View File

@@ -0,0 +1,28 @@
package cache
import (
"testing"
"time"
)
func TestMemcache(t *testing.T) {
mem := NewMemcache("127.0.0.1:11211")
var err error
timeoutDuration := 10 * time.Second
if err = mem.Set("username", "silenceper", timeoutDuration); err != nil {
t.Error("set Error", err)
}
if !mem.IsExist("username") {
t.Error("IsExist Error")
}
name := mem.Get("username").(string)
if name != "silenceper" {
t.Error("get Error")
}
if err = mem.Delete("username"); err != nil {
t.Errorf("delete Error , err=%v", err)
}
}

71
context/access_token.go Normal file
View File

@@ -0,0 +1,71 @@
package context
import (
"encoding/json"
"fmt"
"sync"
"time"
"github.com/silenceper/wechat/util"
)
const (
//AccessTokenURL 获取access_token的接口
AccessTokenURL = "https://api.weixin.qq.com/cgi-bin/token"
)
//ResAccessToken struct
type ResAccessToken struct {
ErrorCode int32 `json:"errcode"`
ErrorMsg string `json:"errmsg"`
AccessToken string `json:"access_token"`
ExpiresIn int32 `json:"expires_in"`
}
//SetAccessTokenLock 设置读写锁一个appID一个读写锁
func (ctx *Context) SetAccessTokenLock(l *sync.RWMutex) {
ctx.accessTokenLock = l
}
//GetAccessToken 获取access_token
func (ctx *Context) GetAccessToken() (accessToken string, err error) {
ctx.accessTokenLock.Lock()
defer ctx.accessTokenLock.Unlock()
accessTokenCacheKey := fmt.Sprintf("access_token_%s", ctx.AppID)
val := ctx.Cache.Get(accessTokenCacheKey)
if val != nil {
accessToken = val.(string)
return
}
//从微信服务器获取
var resAccessToken ResAccessToken
resAccessToken, err = ctx.GetAccessTokenFromServer()
if err != nil {
return
}
accessToken = resAccessToken.AccessToken
return
}
//GetAccessTokenFromServer 强制从微信服务器获取token
func (ctx *Context) GetAccessTokenFromServer() (resAccessToken ResAccessToken, err error) {
url := fmt.Sprintf("%s?grant_type=client_credential&appid=%s&secret=%s", AccessTokenURL, ctx.AppID, ctx.AppSecret)
var body []byte
body, err = util.HTTPGet(url)
err = json.Unmarshal(body, &resAccessToken)
if err != nil {
return
}
if resAccessToken.ErrorMsg != "" {
err = fmt.Errorf("get access_token error : errcode=%v , errormsg=%v", resAccessToken.ErrorCode, resAccessToken.ErrorMsg)
return
}
accessTokenCacheKey := fmt.Sprintf("access_token_%s", ctx.AppID)
err = ctx.Cache.Set(accessTokenCacheKey, resAccessToken.AccessToken, time.Duration(resAccessToken.ExpiresIn)-1500/time.Second)
return
}

View File

@@ -1,6 +1,11 @@
package context
import "net/http"
import (
"net/http"
"sync"
"github.com/silenceper/wechat/cache"
)
//Context struct
type Context struct {
@@ -9,12 +14,13 @@ type Context struct {
Token string
EncodingAESKey string
Cache cache.Cache
Writer http.ResponseWriter
Request *http.Request
}
func (ctx *Context) getAccessToken() {
//accessTokenLock 读写锁 同一个AppID一个
accessTokenLock *sync.RWMutex
}
// Query returns the keyed url query value if it exists

19
util/http.go Normal file
View File

@@ -0,0 +1,19 @@
package util
import (
"io/ioutil"
"net/http"
)
//HTTPGet get 请求
func HTTPGet(url string) ([]byte, error) {
response, err := http.Get(url)
if err != nil {
return nil, err
}
return ioutil.ReadAll(response.Body)
}
//HTTPPost post 请求
func HTTPPost() {
}

View File

@@ -2,7 +2,9 @@ package wechat
import (
"net/http"
"sync"
"github.com/silenceper/wechat/cache"
"github.com/silenceper/wechat/context"
"github.com/silenceper/wechat/server"
)
@@ -18,6 +20,7 @@ type Config struct {
AppSecret string
Token string
EncodingAESKey string
Cache cache.Cache
}
//NewWechat init
@@ -32,6 +35,8 @@ func copyConfigToContext(cfg *Config, context *context.Context) {
context.AppSecret = cfg.AppSecret
context.Token = cfg.Token
context.EncodingAESKey = cfg.EncodingAESKey
context.Cache = cfg.Cache
context.SetAccessTokenLock(new(sync.RWMutex))
}
//GetServer init