omniauth-wechat-oauth2 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +31 -0
- data/lib/omniauth/strategies/qiye_web.rb +59 -0
- data/lib/omniauth/strategies/wechat_qiye.rb +12 -24
- data/lib/omniauth/strategies/wecom_validation.rb +62 -0
- data/lib/omniauth/wechat.rb +1 -0
- data.tar.gz.sig +0 -0
- metadata +30 -31
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 80313d7db1a1d6df69ed886099adead9279872a8fb49de1b8b961a8483fd6276
|
|
4
|
+
data.tar.gz: db075a26ae635ab40180b0b3f937bbad0484111c06dd54d3512067424e31c74b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 65f903b8e65eedb5017d1763919b92679e0f798eb3dd3df22d66067ba28e3e9d4492ed9b755249ec0b0cd57e53f7fcb61d058930b892c65a931bf756c686bc70
|
|
7
|
+
data.tar.gz: 1a95f075d1f32e42feca3ade502f874ca455832a8da6fc466c298f470fa28530773e256de98260c345f9adb83053d73da935576a02a2eb8adf0bddd72d48602c
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/README.md
CHANGED
|
@@ -93,6 +93,37 @@ Here's an example of an authentication hash available in the callback by accessi
|
|
|
93
93
|
|
|
94
94
|
## Wechat Qiye OAuth2
|
|
95
95
|
|
|
96
|
+
Both enterprise strategies (`qiye_web` and `wechat_qiye`) require a successful
|
|
97
|
+
WeCom API response (`errcode: 0`) and a nonempty member `userid`. A corporate
|
|
98
|
+
access token does not authenticate a user: the callback's authorization code
|
|
99
|
+
must also resolve to a member. Invalid codes, API errors, malformed responses,
|
|
100
|
+
and nonmember identities fail authentication without invoking the application
|
|
101
|
+
callback. TLS certificate verification is enabled by default.
|
|
102
|
+
|
|
103
|
+
### WeCom web login
|
|
104
|
+
|
|
105
|
+
```ruby
|
|
106
|
+
config.omniauth :qiye_web, ENV['WECOM_CORP_ID'], ENV['WECOM_CORP_SECRET'],
|
|
107
|
+
agentid: ENV['WECOM_AGENT_ID']
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Start login through OmniAuth's POST request phase with your application's CSRF
|
|
111
|
+
protection. Keep `provider_ignores_state` at its default (`false`): the callback
|
|
112
|
+
must return the generated state in the same browser session. State is consumed
|
|
113
|
+
when checked, so a completed callback cannot be replayed. If valid logins fail
|
|
114
|
+
with `csrf_detected`, check the session cookie, callback host, and proxy/HTTPS
|
|
115
|
+
configuration instead of disabling state validation.
|
|
116
|
+
|
|
117
|
+
When upgrading an existing deployment, publish or pin the fixed gem revision,
|
|
118
|
+
update the application's lockfile, and restart its processes. A Bundler local
|
|
119
|
+
override only changes the developer's checkout. This fix does not invalidate
|
|
120
|
+
previously issued application sessions or tokens; revoke those associated with
|
|
121
|
+
any confirmed unauthorized login separately. Applications should also reject
|
|
122
|
+
blank `auth.uid` values before looking up local accounts and avoid logging the
|
|
123
|
+
full authentication hash, which contains credentials.
|
|
124
|
+
|
|
125
|
+
### Legacy enterprise OAuth2
|
|
126
|
+
|
|
96
127
|
Wechat Qiey usage and configuration are the same with normal account above.
|
|
97
128
|
|
|
98
129
|
```ruby
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require "omniauth-oauth2"
|
|
2
|
+
require "omniauth/strategies/wecom_validation"
|
|
3
|
+
|
|
4
|
+
module OmniAuth
|
|
5
|
+
module Strategies
|
|
6
|
+
class QiyeWeb < OmniAuth::Strategies::OAuth2
|
|
7
|
+
include WecomValidation
|
|
8
|
+
|
|
9
|
+
option :name, 'qiye_web'
|
|
10
|
+
|
|
11
|
+
option :client_options, { site: 'https://qyapi.weixin.qq.com',
|
|
12
|
+
authorize_url: 'https://login.work.weixin.qq.com/wwlogin/sso/login',
|
|
13
|
+
token_url: '/cgi-bin/gettoken',
|
|
14
|
+
token_method: :get }
|
|
15
|
+
|
|
16
|
+
option :authorize_options, %i[agentid state login_type]
|
|
17
|
+
option :token_params, { parse: :json }
|
|
18
|
+
option :agentid, nil
|
|
19
|
+
|
|
20
|
+
uid do
|
|
21
|
+
raw_info
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
info do
|
|
25
|
+
{ userid: uid }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
extra do
|
|
29
|
+
{ raw_info: nil }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Inherit OAuth2#callback_phase so state, provider errors, and failures are
|
|
33
|
+
# checked before an authentication hash can reach the application.
|
|
34
|
+
def request_phase
|
|
35
|
+
raise ArgumentError, 'agentid is required for QiyeWeb strategy' if options.agentid.to_i <= 0
|
|
36
|
+
|
|
37
|
+
ap = authorize_params
|
|
38
|
+
params = {
|
|
39
|
+
'login_type' => ap[:login_type] || 'CorpApp',
|
|
40
|
+
'appid' => client.id,
|
|
41
|
+
'agentid' => options.agentid,
|
|
42
|
+
'redirect_uri' => callback_url,
|
|
43
|
+
'state' => ap[:state]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
redirect client.authorize_url(params)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def raw_info
|
|
50
|
+
@uid ||= begin
|
|
51
|
+
access_token.options[:mode] = :query
|
|
52
|
+
response = access_token.get('/cgi-bin/auth/getuserinfo',
|
|
53
|
+
params: { 'code' => authorization_code }, parse: :json)
|
|
54
|
+
wecom_userid(wecom_response(response))
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
require "omniauth-oauth2"
|
|
2
|
+
require "omniauth/strategies/wecom_validation"
|
|
2
3
|
|
|
3
4
|
module OmniAuth
|
|
4
5
|
module Strategies
|
|
5
6
|
class WechatQiye < OmniAuth::Strategies::OAuth2
|
|
7
|
+
include WecomValidation
|
|
8
|
+
|
|
6
9
|
option :name, "wechat_qiye"
|
|
7
10
|
|
|
8
11
|
option :client_options, {
|
|
9
12
|
:site => "https://qyapi.weixin.qq.com",
|
|
10
13
|
authorize_url: "https://open.weixin.qq.com/connect/oauth2/authorize#wechat_redirect",
|
|
11
14
|
token_url: "/cgi-bin/gettoken",
|
|
12
|
-
token_method: :get
|
|
13
|
-
connection_opts: {
|
|
14
|
-
ssl: { verify: false }
|
|
15
|
-
}
|
|
15
|
+
token_method: :get
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
option :authorize_params, {scope: "snsapi_userinfo"}
|
|
@@ -46,35 +46,23 @@ module OmniAuth
|
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
def raw_info
|
|
49
|
-
# step 2: get userid via code and access_token
|
|
50
|
-
@code ||= access_token[:code]
|
|
51
|
-
|
|
52
|
-
# step 3: get user info via userid
|
|
53
49
|
@uid ||= begin
|
|
54
50
|
access_token.options[:mode] = :query
|
|
55
|
-
response = access_token.get('/cgi-bin/user/getuserinfo',
|
|
56
|
-
|
|
51
|
+
response = access_token.get('/cgi-bin/user/getuserinfo',
|
|
52
|
+
:params => {'code' => authorization_code}, parse: :json)
|
|
53
|
+
wecom_userid(wecom_response(response))
|
|
57
54
|
end
|
|
58
55
|
|
|
59
56
|
@raw_info ||= begin
|
|
60
57
|
access_token.options[:mode] = :query
|
|
61
58
|
response = access_token.get("/cgi-bin/user/get", :params => {"userid" => @uid}, parse: :json)
|
|
62
|
-
response
|
|
59
|
+
data = wecom_response(response)
|
|
60
|
+
unless wecom_userid(data).casecmp(@uid).zero?
|
|
61
|
+
raise CallbackError.new(:invalid_uid, 'WeCom member profile does not match the authenticated userid')
|
|
62
|
+
end
|
|
63
|
+
data
|
|
63
64
|
end
|
|
64
65
|
end
|
|
65
|
-
|
|
66
|
-
protected
|
|
67
|
-
def build_access_token
|
|
68
|
-
# step 0: wechat respond code
|
|
69
|
-
code = request.params['code']
|
|
70
|
-
|
|
71
|
-
# step 1: get access token
|
|
72
|
-
params = {
|
|
73
|
-
'corpid' => client.id,
|
|
74
|
-
'corpsecret' => client.secret,
|
|
75
|
-
}.merge(token_params.to_hash(symbolize_keys: true))
|
|
76
|
-
client.get_token(params, deep_symbolize(options.auth_token_params.merge({code: code})))
|
|
77
|
-
end
|
|
78
66
|
end
|
|
79
67
|
end
|
|
80
68
|
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module OmniAuth
|
|
2
|
+
module Strategies
|
|
3
|
+
# WeCom returns API failures as HTTP 200 responses. A corporate access token
|
|
4
|
+
# alone does not authenticate the user presenting the callback code.
|
|
5
|
+
module WecomValidation
|
|
6
|
+
protected
|
|
7
|
+
|
|
8
|
+
def secure_compare(left, right)
|
|
9
|
+
return false unless left.is_a?(String) && right.is_a?(String)
|
|
10
|
+
|
|
11
|
+
super
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def authorization_code
|
|
15
|
+
code = request.params['code']
|
|
16
|
+
unless code.is_a?(String) && !code.strip.empty?
|
|
17
|
+
raise OAuth2::CallbackError.new(:invalid_code, 'Missing or invalid WeCom authorization code')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
code
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def build_access_token
|
|
24
|
+
authorization_code
|
|
25
|
+
params = {
|
|
26
|
+
'corpid' => client.id,
|
|
27
|
+
'corpsecret' => client.secret
|
|
28
|
+
}.merge(token_params.to_hash(symbolize_keys: true))
|
|
29
|
+
|
|
30
|
+
client.get_token(params, deep_symbolize(options.auth_token_params)).tap do |token|
|
|
31
|
+
unless token && token.token.is_a?(String) && !token.token.strip.empty?
|
|
32
|
+
raise OAuth2::CallbackError.new(:invalid_token, 'Missing WeCom access token')
|
|
33
|
+
end
|
|
34
|
+
validate_wecom_response(token.params)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def wecom_response(response)
|
|
39
|
+
validate_wecom_response(response.parsed)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def validate_wecom_response(data)
|
|
43
|
+
unless data.is_a?(Hash) && data['errcode'] == 0
|
|
44
|
+
raise OAuth2::CallbackError.new(:invalid_response, 'WeCom API did not return a successful response')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
data
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def wecom_userid(data)
|
|
51
|
+
# Support both the current API and the legacy UserId response. OAuth2's
|
|
52
|
+
# SnakyHash also accepts the original spelling of normalized keys.
|
|
53
|
+
userid = data['userid'] || data['UserId']
|
|
54
|
+
unless userid.is_a?(String) && !userid.strip.empty?
|
|
55
|
+
raise OAuth2::CallbackError.new(:invalid_uid, 'WeCom did not return a member userid')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
userid
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
data/lib/omniauth/wechat.rb
CHANGED
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,43 +1,42 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: omniauth-wechat-oauth2
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex Hu
|
|
8
8
|
- Never Min
|
|
9
9
|
- Eric Guo
|
|
10
|
-
autorequire:
|
|
11
10
|
bindir: bin
|
|
12
11
|
cert_chain:
|
|
13
12
|
- |
|
|
14
13
|
-----BEGIN CERTIFICATE-----
|
|
15
14
|
MIIEeDCCAuCgAwIBAgIBATANBgkqhkiG9w0BAQsFADBBMRMwEQYDVQQDDAplcmlj
|
|
16
15
|
Lmd1b2N6MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZFgNj
|
|
17
|
-
|
|
16
|
+
b20wHhcNMjYwNTIyMTUyNDI0WhcNMjcwNTIyMTUyNDI0WjBBMRMwEQYDVQQDDApl
|
|
18
17
|
cmljLmd1b2N6MRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
/
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
18
|
+
FgNjb20wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC49ueF2WFVqQye
|
|
19
|
+
d1kwtvBNyXx9AI8fLWwLHJqf+3ojjWEYwf8NtwYbBgptw7sMDfbpu+H0TjLSYW9e
|
|
20
|
+
R5IVlfP0v55JtDNjZLnQTtXxaiGLZ9aZgT1t5Rn42RSYqfjLKN2maKpRUCnw8Tw4
|
|
21
|
+
+G1tdxFnYIsHda7jiNvetZjqeVhaoN4enfPk2pTeHpmXvH/FzLuKRkPz0yQOFD6P
|
|
22
|
+
IFdE1a4sPs7Fk9QJa6zyPQ/7cL1Uu+IjNzibvTot+Go1GtWvc7bqdDueX6MSo9Ki
|
|
23
|
+
7XBVH4Svk9BqGKKCJFibYjBRxMbzlwA8fik9JUKj9Q0gmXeRRf+tQUZWJHKF5Y/4
|
|
24
|
+
wzqyT6k4u5e3S/QnpD/ZNo1ESiu1Bxc6KvlIihKlOvA8+RSgSAmZtcHhk2en4DtP
|
|
25
|
+
aeBgCrJABFbkMVk9+OiRcq1kDAIJHnH9XxyrM/s4x5FYPgZWbqfbYltHp+Y9ByNw
|
|
26
|
+
uzG6YQkT6PkKRAdl8i6udI70iLQZIE8sI+4bwl3JnTfDrJsklhsCAwEAAaN7MHkw
|
|
27
|
+
CQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFAAS4PVX34FrNYW9Iv16
|
|
28
|
+
R4Qyoj1CMB8GA1UdEQQYMBaBFGVyaWMuZ3VvY3pAZ21haWwuY29tMB8GA1UdEgQY
|
|
29
|
+
MBaBFGVyaWMuZ3VvY3pAZ21haWwuY29tMA0GCSqGSIb3DQEBCwUAA4IBgQBFdbRh
|
|
30
|
+
Wh50P882h5BMysO8Ru/cnqUENIsHxUnZsssHuFcU3Gn3Sq43ixKzFhA4uOCDfY36
|
|
31
|
+
xvX7johxHhukDAdo4lD9h+f5Vck35Qns5Ln+b0o0iTyENOFou57CgeqpWeVkDIi4
|
|
32
|
+
vlwdgCunr64KKW7snC4E76AUXRnOYC0UhZL2VQRc54sN6eMIACogJ9ZHii3h5FmG
|
|
33
|
+
ep6LMfi1oKBrU7MLT5BidvCxG3ePEtdfACGznDE7GgimLVcsb3Ft+sNeP6fBtvrM
|
|
34
|
+
OljHZezOIi+Wbot4pvwdt8tCI4eCoAWAYuoCtyav5dDRUeqI7TPdQGgMPDcVckNE
|
|
35
|
+
e3iKcBAe/0pRYSZxORE63n3SOo9MPL2oGe9A21LR/tk/CJ8kZxDdeTh4zL+Ufw3R
|
|
36
|
+
G4TR+pkSPTTDPI2Ft/RAqHjqectqrcz4gZ4e/x1nBhoF8QKrBuEvHXNTR5EtMzcz
|
|
37
|
+
CU8I1U00X8GGbinHiVIfDJnOkCq7cBmbTamZpNwZLCrgQupqUNhEP2vcZVg=
|
|
39
38
|
-----END CERTIFICATE-----
|
|
40
|
-
date:
|
|
39
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
41
40
|
dependencies:
|
|
42
41
|
- !ruby/object:Gem::Dependency
|
|
43
42
|
name: omniauth-oauth2
|
|
@@ -45,28 +44,28 @@ dependencies:
|
|
|
45
44
|
requirements:
|
|
46
45
|
- - ">="
|
|
47
46
|
- !ruby/object:Gem::Version
|
|
48
|
-
version: 1.
|
|
47
|
+
version: 1.8.0
|
|
49
48
|
type: :runtime
|
|
50
49
|
prerelease: false
|
|
51
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
52
51
|
requirements:
|
|
53
52
|
- - ">="
|
|
54
53
|
- !ruby/object:Gem::Version
|
|
55
|
-
version: 1.
|
|
54
|
+
version: 1.8.0
|
|
56
55
|
- !ruby/object:Gem::Dependency
|
|
57
56
|
name: rspec
|
|
58
57
|
requirement: !ruby/object:Gem::Requirement
|
|
59
58
|
requirements:
|
|
60
59
|
- - "~>"
|
|
61
60
|
- !ruby/object:Gem::Version
|
|
62
|
-
version: 3.
|
|
61
|
+
version: 3.13.1
|
|
63
62
|
type: :development
|
|
64
63
|
prerelease: false
|
|
65
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
66
65
|
requirements:
|
|
67
66
|
- - "~>"
|
|
68
67
|
- !ruby/object:Gem::Version
|
|
69
|
-
version: 3.
|
|
68
|
+
version: 3.13.1
|
|
70
69
|
description: Using OAuth2 to authenticate wechat user when web resources being viewed
|
|
71
70
|
within wechat(weixin) client.
|
|
72
71
|
email:
|
|
@@ -79,14 +78,15 @@ extra_rdoc_files: []
|
|
|
79
78
|
files:
|
|
80
79
|
- README.md
|
|
81
80
|
- lib/omniauth-wechat-oauth2.rb
|
|
81
|
+
- lib/omniauth/strategies/qiye_web.rb
|
|
82
82
|
- lib/omniauth/strategies/wechat.rb
|
|
83
83
|
- lib/omniauth/strategies/wechat_qiye.rb
|
|
84
|
+
- lib/omniauth/strategies/wecom_validation.rb
|
|
84
85
|
- lib/omniauth/wechat.rb
|
|
85
86
|
homepage: https://github.com/nevermin/omniauth-wechat-oauth2
|
|
86
87
|
licenses:
|
|
87
88
|
- MIT
|
|
88
89
|
metadata: {}
|
|
89
|
-
post_install_message:
|
|
90
90
|
rdoc_options: []
|
|
91
91
|
require_paths:
|
|
92
92
|
- lib
|
|
@@ -102,8 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
102
102
|
version: '0'
|
|
103
103
|
requirements:
|
|
104
104
|
- none
|
|
105
|
-
rubygems_version:
|
|
106
|
-
signing_key:
|
|
105
|
+
rubygems_version: 4.0.22
|
|
107
106
|
specification_version: 4
|
|
108
107
|
summary: Omniauth strategy for wechat(weixin)
|
|
109
108
|
test_files: []
|
metadata.gz.sig
CHANGED
|
Binary file
|