With the strong focus on privacy, browsers have recently started phasing out support for the 3rd party cookie. This has caused issues for embedded apps which until now have required the use of 3rd party cookies.
Our new App Bridge auth beta introduces “session tokens” to empower developers to create faster, more flexible, and more compatible apps. Session token based auth does not depend on cookies and instead relies on a Shopify-generated token that your app needs to send with every request.
In order to get started with App Bridge auth, or migrate your current app from traditional, cookie-based authentication, you can follow the guide in our developer documentation.
Questions about App Bridge auth or session tokens? Post them in this board or reach out to support through your partner dashboard.
@dsingh In the 5 years I've used Shopify I've never seen a myshopify url changed or recycled into a new store. When you try to signup using one that was ever used before it gives an error. Even if it were recycled at some point, in that scenario, you should be processing the web hook you receive a few days after any app is uninstalled and wipe out all the data for that store.
A few days! Heck, it should be dealt with prompter than that. When a shop closes, and Shopify sends the App Uninstalled webhook, we're talking mere minutes at the most! Why wait around days! It is likely that recycling those names is possible, but I would not stress on it either, as you always start with a fresh slate of name, and ID's if you're doing it right.
I think I still own flowers.myshopify.com and cars.myshopify.com if anybody wants... haha. Going back to 2006 I bet. When it failed to occur to me that shop domain name matters for nothing save it is the unique ID of the shop.
@HunkyBill Agreed, I'd prefer to use the shop id (just to be certain). But We can't depend on callbacks for data security. Callbacks fail, endpoints can be unavailable, etc. FWIK I think that JWT only gives us the user id for the active user and the shop url/domain. That probably isn't the best information to authenticate using JWT. Does that makes sense?
I am not going to argue for or against JWT. If a couple of billion dollar companies decided it was OK to use them, and the code provided to use them was not written by me, but by experts in that domain, I leave it to them that it just works. Rolling your own always involves mistakes and holes, so I leave you to decide for yourself what you do. I just know that webhooks are retried till they succeed, or the webhook is deleted because the App never responded in a good many days.
@HunkyBill I'm not arguing for or against JWT. There is no issue with that. What I'm saying is that maybe Shopify should pass the Shop ID, instead of User ID in the JWT token. We(partners) don't receive the User ID during the OAuth process. The ID which we get through OAuth is the Shop ID (AFAIK).
- We're receiving Shop ID and Shop Domain
- We're receiving User ID and Shop Domain
Ok cool. I am surprised Shopify would screw up the basics, but it what you're pointing out is a basic screwup, then best it get sorted now, before everyone gets pumped and primed and then lost due to this. I think you can setup a flow where you do get a UserID, but certainly not everyone uses that, so it remains a fringe benefit, not the main course meal.
I think you both aren't understanding the point of JWT. It's stateless authentication. It has no knowledge if you are storing offline or online access tokens behind the scenes. A JWT sub will always be a user id because it's the user who is invoking the action. If it's an offline token, simply use the domain to pull the token via the domain. myshopify domains don't recycle and cannot be changed. You can add an uninstall webhooks that trigger right at uninstall and you also receive revoke webhooks automatically if you don't have an uninstall webhook. You're making it way more confusing than it needs to be.
Offline token? Use `dest` for the check to grab the offline token.
Online token? Use `sub`.
Hell you could even make another table that associates user_ids with a specific domain.
Thanks for the opinion. My two cents, your english does not communicate your true knowledge on the subject, but instead provides a fleeting glimpse that perhaps you know and understand the subject, but not well enough to really explain it. Perhaps in a blog post, with explicit examples, what you just said would be comprehensible.
This is not a thread for code, teaching or evaluating JWT. Shopify simply threw it out there and expects it to have uptake. Clearly this is the beginning of the journey for most. Throwing out terms like dest and sub with no context as to what those are, or mean, adds nothing to the convo.
Sorry. Just my opining.
I expect that one day soon, JWT will in fact be a useful pattern for most, but at this time, it remains sketch at best to bother with it, unless one of two things:
1. you already implemented JWT as an authentication scheme, no one hacked you when you did it wrong, it all works, and you can do it in your sleep now
2. you are sick and tired of the third-party cookie effort, and desperately want to get off it, and will invest N hours (n between 0 and 100) in learning JWT ala Shopify.
Personally, with all the stuff currently broken, borked or painful with Shopify Apps, I am going to wait a bit to see how JWT takes off and becomes mainstream before I waste too many hours with it.
@KisukaKiza If you're at all concerned about security you wouldn't use the shopify domain to verify the logged in user/access. There is a possibility for it to be modified (until or unless Shopify says otherwise).
As for your idea to maintain a user ids list: What happens when a store owner removes access for a user and your list is out of date now? Now, this is just hypothetical and I'm pretty sure that the token will expire soon enough after so it won't be valid anymore. But, that being said; "almost" secure isn't an option for me if I want to sleep at night.
Shopify doesn't provide partner with any information through Open Auth about "who" the logged in user is unless you are using online tokens in which case associated_user is returned but that might not be useful for most of the Partners/App developers who require offline tokens to check for new orders/customers. Cleanest solution to this probably would be to allow the developers to receive token or a Shop or a User. Shop token for apps using offline tokens and User token for apps using online tokens.
i.e. getSessionToken(APP, USER_OR_SHOP);
This can return a shop or user id in the token it returns depending upon what if we're trying to authenticate a shop or a user. This is just my opinion and I haven't thought too much about this. I'm just trying to throw my two cents in the basket.
For what it's worth this is a beta release and bound to have issues in it. Let's just all calm down and help Shopify build a better solution for us by testing it and providing feedback. I'm sure I'm not the only one who's annoyed by the safari ITP issues and I'm sure other browsers aren't too far behind in adding similar limitations on 3rd party cookies.
Not sure what's with the aggro attitude guys. I don't work for Shopify, I'm just another developer trying to provide some help as someone who has experience with JWTs and implemented the solution that Shopify has put into beta. My example I gave a few posts ago was for an online access token based app.
Regarding the dest and sub terminology, I assumed you read the docs they linked at the start of this topic which explains what those contain: https://shopify.dev/tools/app-bridge/authentication See "Payload" to know what those fields are.
As for JWT at a whole, this is not new. This authentication method has been around since 2010. You can read up on JWTs here: https://jwt.io
In regards to the security of JWT, they are signed with their payloads. You cannot manipulate a JWT because it will fail the validation check. Second, you always validate the integrity of the JWT when it's sent to your server / protected route prior to doing anything else. JWTs are also short-lived tokens, they do not last forever and are always different. You do not store JWT tokens ever either because they are stateless.
I'm not entirely sure what you mean on the last part. Those functions should NEVER be returning an access token. Access tokens are only ever generated after your oauth callback. The JWT is your "login" mechanism to know what access token you need to use to make queries.
Sorry if I'm not helping much, but I'm not entirely sure you guys are doing much research into JWTs in general judging from the content of your replies.
Honestly, the flow charts on https://shopify.dev/tools/app-bridge/authentication sum up the entire concept very well once you understand both the oAuth flow on Shopify with App Bridge, and the underlying principals of how JWTs work.
Not a question about JWT. They exist, are not new, and can be understood when you choose to dig in! You win there.
The problem is that recently (last 3 years or so), things have changed a lot with how Shopify works and how browsers work. Shopify has gamely tried to keep up, but it turns out the be both hard and painful since some things (browsers) are out of their control.
So this introduction to JWT could have gone smooth as butter, had the whole thing been introduced from scratch, as a thing. Instead, it was merged into the ongoing, constantly fluxing App gem, and the two do not necessarily mesh/merge well. To me, that is the main issue. I leave out and skip how this affects other projects and their individual woes with it (anything Node or Python or PHP for example).
And as a final note, it is new, and not the easiest thing in the world to comprehend and understand the App Bridge itself. Can you point out any nice deep dives into it? I have found zero, save for scrounging the code and issues. I guess my point is not being aggro to you, but to point out, that while for YOU it may all be easy and make sense, your specialization in that may prevent you from recognizing how much work it is to not only dissect the finer points of it (JWT) but also to make it servicable inside Shopify Apps, and with the constantly evolving App Bridge. Moving targets are not ideal to trick out with even the grand daddy's of authorization, so of course this issue persists.
You make out like it is a lack of desire on the community to learn JWT as the issue, which is in some part true. Over the years I myself have conferred that advice a lot, RTFM, when appropriate. I am not seeing anything yet where it is RTFM but instead, this is just complaints directed at no one in particular, because we have to adopt something that is awkward to use, and soon.
FWIW, while I think we would've been better off using something other than the myshopify.com domain as a permanent identifier, you can rely on the myshopify.com domain as a stable identifier for a shop.
Our Ruby reference implementation associates the myshopify.com domain with the Admin API token returned via OAuth. You can then use the `dest` claim in the JWT (which contains the myshopify.com domain) to lookup the correct Admin API token and use it to make requests on behalf of the shop. (This assumes that you're not using "online tokens", which are tied to a particular user, in which case you should use the `sub` claim which contains the user ID.)
@Michael_Ragalie Thank you for the clarification! I just wanted to make sure that we can use the shopify domain. Do we have a ballpark when this will be out of beta? We already have our implementation ready to roll out. This will make the experience consistent and much better for users.
We're aiming to bring it out of beta end of September/early October. First we're following up on some of the feedback from this thread and other venues to make sure this is something developers feel comfortable adopting 🙂
If it's working for you, feel free to use it in production (we have several apps doing so already, including some of our most used internal apps). Technically we reserve the right to make breaking changes until it's out of beta, but it's looking unlikely we will actually do so.
@Michael_Ragalie yeah it's pretty solid already honestly, I have it running in production with my app. The only issue I really have is you guys need to do some better documentation for app bridge in general. I wanted to know more about the new app bridge utils involving this new auth method, but I had to resort to looking in node_modules to find how how each of those new classes worked under the hood and what options I had with them. There are links to README files on the npm package but those take you to the internal repo which nobody has access to. Would be nice to at the very least have some kind of public documentation on some of these classes and other app bridge elements so we can fully understand them.
I was able to able to get this running in production as well using the info that @KisukaKiza posted on this thread along with the docs. I did end up taking the koa-shopify-auth and graphqlproxy packages and stripped them of cookie cruft, and consolidated a few things.
One of the things that would be nice to know more about is whether we can also still use a Provider after using createApp. It would be great if there was something like an app prop on the Provider where we could pass the already instantiated app. Without that it seems like the useAppBridge hook fails looking for the context.
Otherwise it seems to be working great! I've also tested on Safari, and the Safari Technology Preview and it's loading fast without issues.
Like already mentioned it would be cool to have access to the source on @shopify/app-bridge-utils.
@KisukaKiza thanks again for the great post earlier. Here it is again if anyone missed it:
Thanks for the feedback! We published some documentation on how the helpers work so you don't have to dig into node_modules to use them 🙂