Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove JWT middleware #1861

Merged
merged 4 commits into from
Jun 17, 2024
Merged

Remove JWT middleware #1861

merged 4 commits into from
Jun 17, 2024

Conversation

danielpgross
Copy link
Contributor

@danielpgross danielpgross commented Jun 11, 2024

What this PR does

Closes #1744

Removes the JWT middleware, since JWT authentication was moved to shopify-api-ruby in v19 and then the related ShopifyApp::JWT class was deprecated here (see upgrading guide).

  • There were a few remaining references to the decoded JWT values set by the middleware (e.g. request.env["jwt.shopify_domain"]), notably in ShopifyApp::WithShopifyIdToken
    • ShopifyApp::WithShopifyIdToken has been updated to no longer check values in request.env["jwt.*"], and instead only check header and URL param values
    • Other uses of request.env["jwt.*"] have been updated to use the respective methods in ShopifyApp::WithShopifyIdToken.
  • The jwt gem has been changed from runtime dependency to dev dependency (it's still used to create JWTs in unit tests)

Checklist

Before submitting the PR, please consider if any of the following are needed:

  • Update CHANGELOG.md if the changes would impact users
  • Update README.md, if appropriate.
  • Update any relevant pages in /docs, if necessary
  • For security fixes, the Disclosure Policy must be followed.

@danielpgross danielpgross marked this pull request as ready for review June 11, 2024 20:23
@danielpgross danielpgross requested a review from a team as a code owner June 11, 2024 20:23
Copy link
Member

@tgwizard tgwizard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice! This LGTM, though others should review too.

Admittedly, I'm having troubles following the code that actually ensures a shopify app verifies the ID token is present and valid. The code I'm reading seems to indicate we do some kind of token exchange - but I thought we fully relied on the JWT, without any external calls.

Could you please walk me through the flow?

@danielpgross
Copy link
Contributor Author

Very nice! This LGTM, though others should review too.

Admittedly, I'm having troubles following the code that actually ensures a shopify app verifies the ID token is present and valid. The code I'm reading seems to indicate we do some kind of token exchange - but I thought we fully relied on the JWT, without any external calls.

Could you please walk me through the flow?

Thanks @tgwizard! Will walk you through it according to my understanding:

  1. An app includes the EnsureHasSession concern in a given controller to restrict that controller to requests that are authenticated with a valid session -- think of this as the entry point to the flow.
  2. EnsureHasSession includes LoginProtection and sets up activate_shopify_session from there as an around_action:
    around_action :activate_shopify_session
  3. activate_shopify_session calls current_shopify_session, which calls load_current_sessionand in turn ShopifyAPI::Utils::SessionUtils.current_session_id


    session_id = ShopifyAPI::Utils::SessionUtils.current_session_id(shopify_id_token, cookies, is_online)
  4. Now we're in ShopifyAPI land, and session_id_from_shopify_id_token gets called:
    https://github.com/Shopify/shopify-api-ruby/blob/a64f7dd391306033ca58399b42fa32207ba6dc34/lib/shopify_api/utils/session_utils.rb#L23
  5. The JWT finally gets decoded and then a session ID is generated from it:
    https://github.com/Shopify/shopify-api-ruby/blob/a64f7dd391306033ca58399b42fa32207ba6dc34/lib/shopify_api/utils/session_utils.rb#L48

end

def jwt_payload
@jwt_payload ||= shopify_id_token.present? ? ShopifyAPI::Auth::JwtPayload.new(shopify_id_token) : nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there some way we can skip parsing the JWT token twice, once here, and once in https://github.com/Shopify/shopify-api-ruby/blob/a64f7dd391306033ca58399b42fa32207ba6dc34/lib/shopify_api/utils/session_utils.rb#L48?

(That could be a follow-up optimization).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Looks like that would be a change in the shopify-api-ruby repo, so will leave it as a follow-up.

Copy link
Contributor

@zzooeeyy zzooeeyy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes makes sense to me, have you tried top-hatting with a rails app ?

CHANGELOG.md Outdated Show resolved Hide resolved
@@ -266,6 +265,7 @@ PLATFORMS

DEPENDENCIES
byebug
jwt (>= 2.2.3)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what impact this might have? how did this line get moved?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a result of updating the gemspec as explained in the PR description:

The jwt gem has been changed from runtime dependency to dev dependency (it's still used to create JWTs in unit tests)

yarn.lock Outdated Show resolved Hide resolved
@danielpgross danielpgross force-pushed the remove-jwt-middleware branch 3 times, most recently from 0ee1edd to 8695f06 Compare June 17, 2024 10:54
Copy link
Contributor

@paulomarg paulomarg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@danielpgross
Copy link
Contributor Author

I tested this using a new test app created with https://github.com/Shopify/shopify-app-template-ruby and it's working as expected 👍

Copy link
Contributor

@zzooeeyy zzooeeyy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! Thanks for top-hatting!

docs/Upgrading.md Show resolved Hide resolved
@danielpgross danielpgross merged commit 59c5f1b into main Jun 17, 2024
7 checks passed
@danielpgross danielpgross deleted the remove-jwt-middleware branch June 17, 2024 16:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor JWT to use around_action when needed instead of middleware used with every request
4 participants