Skip to content
This repository has been archived by the owner on Nov 30, 2022. It is now read-only.

Find shop domain in request when getting the token #784

Merged
merged 6 commits into from
May 10, 2021
Merged

Find shop domain in request when getting the token #784

merged 6 commits into from
May 10, 2021

Conversation

squatto
Copy link
Contributor

@squatto squatto commented May 10, 2021

When redirecting within your app, it's easy to get into a state where there isn't a "shop" query param for the token controller to use. At that point you're completely stuck because you can't auth anymore. You're at the end of the road.

This PR adds a static method ShopDomain::getFromRequest() that tries to find the token in the request in multiple ways:

  1. If the request inputs contain "shop" or "shopDomain", it is used.
  2. If the request headers contain "X-Shop-Domain", it is used.
  3. If the request headers have a referrer URL then the same checks are performed against it ("shop" and "shopDomain")
  4. If the referrer URL contains a "token" query param, it is decoded and checked for a shop domain.
    • To accomplish this, I added an optional param to the SessionToken constructor that allows us to not verify the token. This allows us to decode it and get the values regardless of its validity/expiration. It defaults to verifying the token, which is the original functionality.

The end result is that in most cases, the token controller is able to find the shop and you can continue forward as expected.

This allows it to only be decoded - even if it's invalid/expired
1. If the request inputs contain "shop" or "shopDomain", it is returned.
2. If the request inputs contain "token", it is decoded and checked for
a shop domain.
3. If the request has a referrer URL, the same checks are performed
against the referrer URL.
@squatto
Copy link
Contributor Author

squatto commented May 10, 2021

Ah, actually, I just found VerifyShopify::getShopDomainFromRequest(). I'll modify that slightly and use it.

@squatto
Copy link
Contributor Author

squatto commented May 10, 2021

OK this is good to go @osiset 👍🏻

@gnikyt gnikyt merged commit 19a575d into gnikyt:feature/cookieless May 10, 2021
@squatto squatto deleted the get-shop-from-request-for-token branch May 10, 2021 18:17
@gnikyt
Copy link
Owner

gnikyt commented May 10, 2021

@squatto Brain was slow this morning. Since the base value object implementation uses a static method of ::fromNative, like ShopDomain::fromNative($request->get('shop')), I'm thinking the getFromRequest could be changed to fromRequest(Request $request), for some consistency?

@squatto
Copy link
Contributor Author

squatto commented May 11, 2021

@squatto Brain was slow this morning. Since the base value object implementation uses a static method of ::fromNative, like ShopDomain::fromNative($request->get('shop')), I'm thinking the getFromRequest could be changed to fromRequest(Request $request), for some consistency?

I'm good with that. I think it's definitely more consistent. Do you want me to refactor and submit a PR?

@gnikyt
Copy link
Owner

gnikyt commented May 11, 2021

@squatto I can grab it and do it for you :) no worries.

onurkose pushed a commit to onurkose/laravel-shopify that referenced this pull request Jun 25, 2021
* Add param to constructor to optionally not verify the token

This allows it to only be decoded - even if it's invalid/expired

* Add static method `ShopDomain::getFromRequest()` to find the shop domain

1. If the request inputs contain "shop" or "shopDomain", it is returned.
2. If the request inputs contain "token", it is decoded and checked for
a shop domain.
3. If the request has a referrer URL, the same checks are performed
against the referrer URL.

* Find the shop domain in the request

* Remove extraneous `ShopDomain` call

* Use modified process from `VerifyShopify::getShopDomainFromRequest()`

* Use `ShopDomain::getFromRequest()` to get the shop domain
gnikyt added a commit that referenced this pull request Jun 25, 2021
* Combined AuthShopify, AuthToken into new VerifyShopify middleware
* SessionToken value object created to verify and validate all aspects of the JWT
* New unauthenticated route and view added
* Removal of ITP, cookie helper, shop session as they're unneeded
* Added Polaris skeleton to token view
* Revised initial package landing page
* Added session ID support
* Moved AuthorizeShop to InstallShop
* Condensed InstallShop and modified to return an array
* Modified InstallShop to track access token update time
* Modified Shop command to track access token update time
* Support for other routes and token usage
* Removed authenticate.oauth route
* Removed oauthfailure method on authenticate controller
* Removed ShopSession class
* Updated shopify-config to reference new authenticate routes (install, token)
* Updated shopify-config to remove old authenticate routes
* Updated ShopModel's getToken to getAccessToken for naming conflict purposes
* Removed old ITP and authenticate routes from built-in route provider
* Updated SHOPIFY_API_REDRIECT to use /install instead of old /authenticate
* Revert authenticate route back to authenticate instead of 'install'
* Updated test class naming for DeleteWebhooks action
* Added TurboLink support
* Change name for test package
* Added getToken helper
* Added missing auth url exception
* Added billing to allowed routes, change token receipt
* Exception added to prevent loop redirects if authorization link is empty
* Added billing payments with tokens
* Removed unused classes
* Added test cases for session token
* Test cases added for session context, verify shop middleware
* Check for "?" in URLs instead of "&" when determining the separator (#777)
* Fix test: use `authenticate.token` instead of `authenticate.oauth` (#776)
* Use `contains()` to support route prefixes (#775)
* Use an env var for the new `turbo_enabled` config setting (#774)
* Updated code to use AuthManager from Laravel instead of auth()
* Updated response codes to use HTTP constants
* Update to BillingController and Billable middleware to remove old ShopSession service
* Remove "token" from the query string of the target URL (#779)
* Feature/cookieless - changes for turbolinks, install app  (#780)
* Redirect if the user clicked on any link before load Turbo
* Find shop domain in request when getting the token (#784)
* Add param to constructor to optionally not verify the token
* Add static method `ShopDomain::getFromRequest()` to find the shop domain
* Remove extraneous `ShopDomain` calls
* Always pass the filtered query params to the token redirect (#785)
* Added TokenRedirect macro for Laravel Redirect
* Added TokenRoute macro for Laravel URL/Route
* Updated ShopDomain::getFromRequest to be ShopDomain::fromRequest for consistency
* Moved HMAC and HMAC generation/comparison to value object (Hmac)
* Move SessionContext to be a composite value object
* Updated to handle Blade session tokens
* Added Blade directive "@sessionToken"
* Added support for jQuery, Turbolinks, and Axios for token bearer
* Added support for ".session-token" to automatically update with the token value
* Update jQuery ajax header Authorization setting (#790)
* Use template style setting for jQuery.ajaxSetup
* Use window.jQuery.ajaxSettings.headers = { } instead of ajaxSetup method
* Clean up on bearer token header settings
* Remove legacy factories package
* Billing flow adjusted to use tokens
* Fix to Kernel testcase referring to old middleware
* Fix to undefined methods for macros
* Remove build and bin folders from repo
* Added test for `tokenRoute`
* Added test for `tokenRedirect`
* Modified `TokenRedirect` and `TokenUrl` macros to use a common base class
* Added test for sessionToken directive
* Fix to SessionContext validity check for domain comparison
* Resolve static method not found for tests on tokenRedirect and tokenRoute

Co-authored-by: Lucas Michot <[email protected]>
Co-authored-by: Vitaly <[email protected]>
Co-authored-by: Scott Carpenter <[email protected]>
Co-authored-by: Tyler King <[email protected]>
Co-authored-by: Vitaliy Dubov <[email protected]>
Co-authored-by: Stephen Sweetland <[email protected]>
Co-authored-by: Tony Le <[email protected]>
Co-authored-by: Lucas Michot <[email protected]>
// All possible methods
$options = [
// GET/POST
DataSource::INPUT()->toNative() => $request->input('shop') ?? $request->input('shopDomain'),
Copy link
Contributor

Choose a reason for hiding this comment

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

doesn't this make it possible to easily spoof any shop?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants