Skip to content

Commit 11cbcae

Browse files
committed
Accept 'id_token' or 'Bearer id_token' format in SessionUtils::current_session_id
1 parent b7c9881 commit 11cbcae

File tree

4 files changed

+66
-33
lines changed

4 files changed

+66
-33
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ Note: For changes to the API, see https://shopify.dev/changelog?filter=api
44

55
## Unreleased
66
- [#1312](https://github.com/Shopify/shopify-api-ruby/pull/1312) Use same leeway for `exp` and `nbf` when parsing JWT
7-
- [#1314](https://github.com/Shopify/shopify-api-ruby/pull/1314) Add new session util method `SessionUtils::session_id_from_shopify_id_token`
7+
- [#1314](https://github.com/Shopify/shopify-api-ruby/pull/1314)
8+
- Add new session util method `SessionUtils::session_id_from_shopify_id_token`
9+
- `SessionUtils::current_session_id` now accepts shopify Id token in the format of `Bearer this_token` or just `this_token`
810

911
## 14.2.0
1012
- [#1309](https://github.com/Shopify/shopify-api-ruby/pull/1309) Add `Session#copy_attributes_from` method

docs/getting_started.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,17 @@ If your app uses client side rendering instead of server side rendering, you wil
5656

5757
For *embedded* apps:
5858

59-
If you have an `HTTP_AUTHORIZATION` header, you can pass the auth header into:
60-
- `ShopifyAPI::Utils::SessionUtils.current_session_id(auth_header, nil, true)` for online (user) sessions or
61-
- `ShopifyAPI::Utils::SessionUtils.current_session_id(auth_header, nil, false)` for offline (store) sessions.
59+
If you have an `HTTP_AUTHORIZATION` header or `id_token` from the request URL params , you can pass that as `shopify_id_token` into:
60+
- `ShopifyAPI::Utils::SessionUtils.current_session_id(shopify_id_token, nil, true)` for online (user) sessions or
61+
- `ShopifyAPI::Utils::SessionUtils.current_session_id(shopify_id_token, nil, false)` for offline (store) sessions.
6262

63-
You can also use `id_token` from the request URL params to get the session ID:
64-
- `ShopifyAPI::Utils::SessionUtils::session_id_from_shopify_id_token(id_token: id_token_from_param, online: true)` for online (user) sessions or
65-
- `ShopifyAPI::Utils::SessionUtils::session_id_from_shopify_id_token(id_token: id_token_from_param, online: false)` for offline (store) sessions.
63+
`current_session_id` accepts shopify_id_token in the format of `Bearer this_token` or just `this_token`.
6664

65+
You can also use this method to get session ID:
66+
- `ShopifyAPI::Utils::SessionUtils::session_id_from_shopify_id_token(id_token: id_token, online: true)` for online (user) sessions or
67+
- `ShopifyAPI::Utils::SessionUtils::session_id_from_shopify_id_token(id_token: id_token, online: false)` for offline (store) sessions.
68+
69+
`session_id_from_shopify_id_token` does **NOT** accept shopify_id_token in the format of `Bearer this_token`, you must pass in `this_token`.
6770

6871
#### Start Making Authenticated Shopify Requests
6972

lib/shopify_api/utils/session_utils.rb

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,16 @@ class << self
1111

1212
sig do
1313
params(
14-
auth_header: T.nilable(String),
14+
shopify_id_token: T.nilable(String),
1515
cookies: T.nilable(T::Hash[String, String]),
1616
online: T::Boolean,
1717
).returns(T.nilable(String))
1818
end
19-
def current_session_id(auth_header, cookies, online)
19+
def current_session_id(shopify_id_token, cookies, online)
2020
if Context.embedded?
21-
if auth_header
22-
matches = auth_header.match(/^Bearer (.+)$/)
23-
unless matches
24-
ShopifyAPI::Logger.warn("Missing Bearer token in authorization header")
25-
raise Errors::MissingJwtTokenError, "Missing Bearer token in authorization header"
26-
end
27-
28-
session_id_from_shopify_id_token(id_token: T.must(matches[1]), online: online)
21+
if shopify_id_token
22+
id_token = shopify_id_token.gsub("Bearer ", "")
23+
session_id_from_shopify_id_token(id_token: id_token, online: online)
2924
else
3025
# falling back to session cookie
3126
raise Errors::CookieNotFoundError, "JWT token or Session cookie not found for app" unless
@@ -48,7 +43,7 @@ def current_session_id(auth_header, cookies, online)
4843
).returns(String)
4944
end
5045
def session_id_from_shopify_id_token(id_token:, online:)
51-
raise Errors::MissingJwtTokenError, "Missing Shopify ID Token" unless id_token
46+
raise Errors::MissingJwtTokenError, "Missing Shopify ID Token" if id_token.nil? || id_token.empty?
5247

5348
payload = Auth::JwtPayload.new(id_token)
5449
shop = payload.shop

test/utils/session_utils_test.rb

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,20 @@ def setup
2525

2626
@jwt_token = JWT.encode(@jwt_payload, ShopifyAPI::Context.api_secret_key, "HS256")
2727
@auth_header = "Bearer #{@jwt_token}"
28+
@expected_online_session_id = "#{@shop}_#{@user_id}"
29+
@expected_offline_session_id = "offline_#{@shop}"
2830
end
2931

3032
def test_gets_online_session_id_from_shopify_id_token
31-
expected_session_id = "#{@shop}_#{@user_id}"
3233
assert_equal(
33-
expected_session_id,
34+
@expected_online_session_id,
3435
ShopifyAPI::Utils::SessionUtils.session_id_from_shopify_id_token(id_token: @jwt_token, online: true),
3536
)
3637
end
3738

3839
def test_gets_offline_session_id_from_shopify_id_token
39-
expected_session_id = "offline_#{@shop}"
4040
assert_equal(
41-
expected_session_id,
41+
@expected_offline_session_id,
4242
ShopifyAPI::Utils::SessionUtils.session_id_from_shopify_id_token(id_token: @jwt_token, online: false),
4343
)
4444
end
@@ -50,11 +50,16 @@ def test_session_id_from_shopify_id_token_raises_invalid_jwt_errors
5050
end
5151

5252
def test_session_id_from_shopify_id_token_raises_missing_jwt_token_error
53-
error = assert_raises(ShopifyAPI::Errors::MissingJwtTokenError) do
54-
ShopifyAPI::Utils::SessionUtils.session_id_from_shopify_id_token(id_token: nil, online: true)
55-
end
53+
[
54+
nil,
55+
"",
56+
].each do |missing_jwt|
57+
error = assert_raises(ShopifyAPI::Errors::MissingJwtTokenError) do
58+
ShopifyAPI::Utils::SessionUtils.session_id_from_shopify_id_token(id_token: missing_jwt, online: true)
59+
end
5660

57-
assert_equal("Missing Shopify ID Token", error.message)
61+
assert_equal("Missing Shopify ID Token", error.message)
62+
end
5863
end
5964

6065
def test_non_embedded_app_current_session_id_raises_cookie_not_found_error
@@ -98,43 +103,71 @@ def test_embedded_app_current_session_id_raises_cookie_not_found_error
98103
end
99104
end
100105

106+
def test_embedded_app_current_session_id_raises_invalid_jwt_token_error
107+
ShopifyAPI::Context.stubs(:embedded?).returns(true)
108+
[
109+
"Bearer invalid_token",
110+
"Bearer",
111+
"invalid_token",
112+
].each do |invalid_token|
113+
assert_raises(ShopifyAPI::Errors::InvalidJwtTokenError, " - #{invalid_token}") do
114+
ShopifyAPI::Utils::SessionUtils.current_session_id(invalid_token, nil, true)
115+
end
116+
end
117+
end
118+
101119
def test_embedded_app_current_session_id_raises_missing_jwt_token_error
102120
ShopifyAPI::Context.stubs(:embedded?).returns(true)
103121

104122
error = assert_raises(ShopifyAPI::Errors::MissingJwtTokenError) do
105123
ShopifyAPI::Utils::SessionUtils.current_session_id("", nil, true)
106124
end
107125

108-
assert_equal("Missing Bearer token in authorization header", error.message)
126+
assert_equal("Missing Shopify ID Token", error.message)
109127
end
110128

111129
def test_embedded_app_current_session_id_returns_online_id_from_auth_header
112130
ShopifyAPI::Context.stubs(:embedded?).returns(true)
113-
expected_session_id = "#{@shop}_#{@user_id}"
114131

115132
assert_equal(
116-
expected_session_id,
133+
@expected_online_session_id,
117134
ShopifyAPI::Utils::SessionUtils.current_session_id(@auth_header, nil, true),
118135
)
119136
end
120137

121138
def test_embedded_app_current_session_id_returns_offline_id_from_auth_header
122139
ShopifyAPI::Context.stubs(:embedded?).returns(true)
123-
expected_session_id = "offline_#{@shop}"
124140

125141
assert_equal(
126-
expected_session_id,
142+
@expected_offline_session_id,
127143
ShopifyAPI::Utils::SessionUtils.current_session_id(@auth_header, nil, false),
128144
)
129145
end
130146

147+
def test_embedded_app_current_session_id_returns_online_id_from_shopify_id_token
148+
ShopifyAPI::Context.stubs(:embedded?).returns(true)
149+
150+
assert_equal(
151+
@expected_online_session_id,
152+
ShopifyAPI::Utils::SessionUtils.current_session_id(@jwt_token, nil, true),
153+
)
154+
end
155+
156+
def test_embedded_app_current_session_id_returns_offline_id_from_shopify_id_token
157+
ShopifyAPI::Context.stubs(:embedded?).returns(true)
158+
159+
assert_equal(
160+
@expected_offline_session_id,
161+
ShopifyAPI::Utils::SessionUtils.current_session_id(@jwt_token, nil, false),
162+
)
163+
end
164+
131165
def test_embedded_app_current_session_id_returns_id_from_auth_header_even_with_cookies
132166
ShopifyAPI::Context.stubs(:embedded?).returns(true)
133167
cookies = { ShopifyAPI::Auth::Oauth::SessionCookie::SESSION_COOKIE_NAME => "cookie_value" }
134-
expected_session_id = "#{@shop}_#{@user_id}"
135168

136169
assert_equal(
137-
expected_session_id,
170+
@expected_online_session_id,
138171
ShopifyAPI::Utils::SessionUtils.current_session_id(@auth_header, cookies, true),
139172
)
140173
end

0 commit comments

Comments
 (0)