Skip to content

Commit 87bcc37

Browse files
committed
oauth
1 parent 06df848 commit 87bcc37

File tree

6 files changed

+225
-4
lines changed

6 files changed

+225
-4
lines changed

apis/oauth/oauth.go

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// Copyright 2020 FastWeGo
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Package oauth 代公众号发起网页授权
16+
package oauth
17+
18+
import (
19+
"encoding/json"
20+
"fmt"
21+
"net/url"
22+
23+
"github.com/fastwego/wxopen"
24+
)
25+
26+
const (
27+
apiGetAccessToken = "/sns/oauth2/component/access_token"
28+
apiRefreshAccessToken = "/sns/oauth2/component/refresh_token"
29+
apiGetUserInfo = "/sns/userinfo"
30+
)
31+
32+
/*
33+
获取用户授权跳转链接
34+
35+
在确保微信公众账号拥有授权作用域(scope 参数)的权限的前提下(一般而言,已微信认证的服务号拥有 snsapi_base 和 snsapi_userinfo),使用微信客户端打开以下链接(严格按照以下格式,包括顺序和大小写,并请将参数替换为实际内容)
36+
37+
See: https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/official_account_website_authorization.html
38+
39+
GET https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE&component_appid=component_appid#wechat_redirect
40+
41+
*/
42+
func GetAuthorizeUrl(ctx *wxopen.Platform, appid string, redirect_uri string, scope string, state string) (redirectUri string, err error) {
43+
uriTpl := "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect"
44+
redirectUri = fmt.Sprintf(uriTpl, appid, url.QueryEscape(redirect_uri), scope, state, ctx.Config.AppId)
45+
return
46+
}
47+
48+
type AccessToken struct {
49+
AccessToken string `json:"access_token"`
50+
ExpiresIn int `json:"expires_in"`
51+
RefreshToken string `json:"refresh_token"`
52+
Openid string `json:"openid"`
53+
Scope string `json:"scope"`
54+
}
55+
56+
/*
57+
通过code换取网页授权access_token
58+
59+
获取第一步的 code 后,请求以下链接获取 access_token 需要注意的是,由于安全方面的考虑,对访问该链接的客户端有 IP 白名单的要求
60+
61+
See: https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/official_account_website_authorization.html
62+
63+
GET https://api.weixin.qq.com/sns/oauth2/component/access_token?appid=APPID&code=CODE&grant_type=authorization_code&component_appid=COMPONENT_APPID&component_access_token=COMPONENT_ACCESS_TOKEN
64+
*/
65+
func GetAccessToken(ctx *wxopen.Platform, appid string, code string) (accessToken AccessToken, err error) {
66+
67+
params := url.Values{}
68+
params.Add("appid", appid)
69+
params.Add("code", code)
70+
params.Add("grant_type", "authorization_code")
71+
params.Add("component_appid", ctx.Config.AppId)
72+
73+
resp, err := ctx.Client.HTTPGet(apiGetAccessToken + "?" + params.Encode())
74+
if err != nil {
75+
return
76+
}
77+
78+
err = json.Unmarshal(resp, &accessToken)
79+
if err != nil {
80+
return
81+
}
82+
return
83+
}
84+
85+
/*
86+
刷新access_token
87+
88+
由于 access_token 拥有较短的有效期,当 access_token 超时后,可以使用 refresh_token 进行刷新,refresh_token 拥有较长的有效期(30 天),当 refresh_token 失效的后,需要用户重新授权
89+
90+
See: https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/official_account_website_authorization.html
91+
92+
GET https://api.weixin.qq.com/sns/oauth2/component/refresh_token?appid=APPID&grant_type=refresh_token&component_appid=COMPONENT_APPID&component_access_token=COMPONENT_ACCESS_TOKEN&refresh_token=REFRESH_TOKEN
93+
*/
94+
func RefreshAccessToken(ctx *wxopen.Platform, appid string, refresh_token string) (accessToken AccessToken, err error) {
95+
params := url.Values{}
96+
params.Add("appid", appid)
97+
params.Add("refresh_token", refresh_token)
98+
params.Add("grant_type", "refresh_token")
99+
params.Add("component_appid", ctx.Config.AppId)
100+
101+
resp, err := ctx.Client.HTTPGet(apiRefreshAccessToken + "?" + params.Encode())
102+
if err != nil {
103+
return
104+
}
105+
106+
err = json.Unmarshal(resp, &accessToken)
107+
if err != nil {
108+
return
109+
}
110+
return
111+
112+
}
113+
114+
type UserInfo struct {
115+
Openid string `json:"openid"`
116+
Nickname string `json:"nickname"`
117+
Sex int64 `json:"sex"`
118+
Province string `json:"province"`
119+
City string `json:"city"`
120+
Country string `json:"country"`
121+
Headimgurl string `json:"headimgurl"`
122+
Privilege []string `json:"privilege"`
123+
Unionid string `json:"unionid"`
124+
}
125+
126+
/*
127+
拉取用户信息
128+
129+
如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了
130+
131+
See: https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/official_account_website_authorization.html
132+
133+
GET https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
134+
*/
135+
func GetUserInfo(ctx *wxopen.Platform, access_token string, openid string) (userInfo UserInfo, err error) {
136+
137+
params := url.Values{}
138+
params.Add("access_token", access_token)
139+
params.Add("openid", openid)
140+
params.Add("lang", "zh_CN")
141+
142+
resp, err := ctx.Client.HTTPGet(apiGetUserInfo + "?" + params.Encode())
143+
if err != nil {
144+
return
145+
}
146+
147+
err = json.Unmarshal(resp, &userInfo)
148+
if err != nil {
149+
return
150+
}
151+
return
152+
}

cmd/apiconfig.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,4 +151,65 @@ var apiConfig = []ApiGroup{
151151
},
152152
},
153153
},
154+
{
155+
Name: `代公众号发起网页授权`,
156+
Package: `oauth`,
157+
Apis: []Api{
158+
{
159+
Name: "获取用户授权跳转链接",
160+
Description: "在确保微信公众账号拥有授权作用域(scope 参数)的权限的前提下(一般而言,已微信认证的服务号拥有 snsapi_base 和 snsapi_userinfo),使用微信客户端打开以下链接(严格按照以下格式,包括顺序和大小写,并请将参数替换为实际内容)",
161+
Request: "GET https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE&component_appid=component_appid#wechat_redirect\n",
162+
See: "https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/official_account_website_authorization.html",
163+
FuncName: "GetAuthorizeUrl",
164+
GetParams: []Param{
165+
{Name: `appid`, Type: `string`},
166+
{Name: `redirect_uri`, Type: `string`},
167+
{Name: `response_type`, Type: `string`},
168+
{Name: `scope`, Type: `string`},
169+
{Name: `state`, Type: `string`},
170+
{Name: `component_appid`, Type: `string`},
171+
},
172+
},
173+
{
174+
Name: "通过code换取网页授权access_token",
175+
Description: "获取第一步的 code 后,请求以下链接获取 access_token 需要注意的是,由于安全方面的考虑,对访问该链接的客户端有 IP 白名单的要求",
176+
Request: "GET https://api.weixin.qq.com/sns/oauth2/component/access_token?appid=APPID&code=CODE&grant_type=authorization_code&component_appid=COMPONENT_APPID&component_access_token=COMPONENT_ACCESS_TOKEN",
177+
See: "https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/official_account_website_authorization.html",
178+
FuncName: "GetAccessToken",
179+
GetParams: []Param{
180+
{Name: `appid`, Type: `string`},
181+
{Name: `code`, Type: `string`},
182+
{Name: `grant_type`, Type: `string`},
183+
{Name: `component_appid`, Type: `string`},
184+
{Name: `component_access_token`, Type: `string`},
185+
},
186+
},
187+
{
188+
Name: "刷新access_token",
189+
Description: "由于 access_token 拥有较短的有效期,当 access_token 超时后,可以使用 refresh_token 进行刷新,refresh_token 拥有较长的有效期(30 天),当 refresh_token 失效的后,需要用户重新授权",
190+
Request: "GET https://api.weixin.qq.com/sns/oauth2/component/refresh_token?appid=APPID&grant_type=refresh_token&component_appid=COMPONENT_APPID&component_access_token=COMPONENT_ACCESS_TOKEN&refresh_token=REFRESH_TOKEN",
191+
See: "https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/official_account_website_authorization.html",
192+
FuncName: "RefreshAccessToken",
193+
GetParams: []Param{
194+
{Name: `appid`, Type: `string`},
195+
{Name: `grant_type`, Type: `string`},
196+
{Name: `component_appid`, Type: `string`},
197+
{Name: `component_access_token`, Type: `string`},
198+
{Name: `refresh_token`, Type: `string`},
199+
},
200+
},
201+
{
202+
Name: "拉取用户信息",
203+
Description: "如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了",
204+
Request: "GET https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN",
205+
See: "https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/official_account_website_authorization.html",
206+
FuncName: "GetUserInfo",
207+
GetParams: []Param{
208+
{Name: `access_token`, Type: `string`},
209+
{Name: `openid`, Type: `string`},
210+
{Name: `lang`, Type: `string`},
211+
},
212+
},
213+
},
214+
},
154215
}

cmd/build.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ func main() {
3232
flag.StringVar(&pkgFlag, "package", "default", "")
3333
flag.Parse()
3434
for _, group := range apiConfig {
35-
if group.Package == "auth" || group.Package == "account" {
36-
continue
37-
}
3835

3936
if group.Package == pkgFlag {
4037
build(group)

doc/apilist.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,12 @@
2626
- [Unbind (/cgi-bin/open/unbind)](https://pkg.go.dev/github.com/fastwego/wxopen/apis/account?tab=doc#Unbind)
2727
- [获取公众号/小程序所绑定的开放平台帐号](https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/api/account/get.html)
2828
- [Get (/cgi-bin/open/get)](https://pkg.go.dev/github.com/fastwego/wxopen/apis/account?tab=doc#Get)
29+
- 代公众号发起网页授权(oauth)
30+
- [获取用户授权跳转链接](https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/official_account_website_authorization.html)
31+
- [GetAuthorizeUrl (/connect/oauth2/authorize)](https://pkg.go.dev/github.com/fastwego/wxopen/apis/oauth?tab=doc#GetAuthorizeUrl)
32+
- [通过code换取网页授权access_token](https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/official_account_website_authorization.html)
33+
- [GetAccessToken (/sns/oauth2/component/access_token)](https://pkg.go.dev/github.com/fastwego/wxopen/apis/oauth?tab=doc#GetAccessToken)
34+
- [刷新access_token](https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/official_account_website_authorization.html)
35+
- [RefreshAccessToken (/sns/oauth2/component/refresh_token)](https://pkg.go.dev/github.com/fastwego/wxopen/apis/oauth?tab=doc#RefreshAccessToken)
36+
- [拉取用户信息](https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Official_Accounts/official_account_website_authorization.html)
37+
- [GetUserInfo (/sns/userinfo)](https://pkg.go.dev/github.com/fastwego/wxopen/apis/oauth?tab=doc#GetUserInfo)

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ go 1.15
55
require (
66
github.com/faabiosr/cachego v0.16.1
77
github.com/fastwego/miniprogram v1.0.0-beta.3
8-
github.com/fastwego/offiaccount v1.0.0-beta.10
8+
github.com/fastwego/offiaccount v1.0.0-beta.11
99
github.com/iancoleman/strcase v0.1.2
1010
)

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ github.com/fastwego/miniprogram v1.0.0-beta.3 h1:TbWtudxcXr9lBV5L/St+XiFSRsi4u0J
99
github.com/fastwego/miniprogram v1.0.0-beta.3/go.mod h1:cvubz7XnRQnzSgAHgN9vn4sp0IU0D88BAtxi0idnIeo=
1010
github.com/fastwego/offiaccount v1.0.0-beta.10 h1:1FL41x9oruO/YZt52RjoJnmQnKY/YUlQOzTRkCb+cSw=
1111
github.com/fastwego/offiaccount v1.0.0-beta.10/go.mod h1:8roSt8OhE2CtdkKOqZnmUdjmmEaoJ2k//Bav/+4BrJQ=
12+
github.com/fastwego/offiaccount v1.0.0-beta.11 h1:DJ2OpusF0/10Q4d5Mpsl+oziYuIIYINUypN+YLohE4I=
13+
github.com/fastwego/offiaccount v1.0.0-beta.11/go.mod h1:8roSt8OhE2CtdkKOqZnmUdjmmEaoJ2k//Bav/+4BrJQ=
1214
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
1315
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
1416
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=

0 commit comments

Comments
 (0)