-
Notifications
You must be signed in to change notification settings - Fork 387
Custom session storage generates multiple session IDs from single app install #224
Comments
Great question @g-hamilton! Sadly, I don't have any answers for you as I have the same issue and trying to figure how to fix it. However, from what I've found for the moment, those 2 tokens have different concerns.
The store token expire after 24h. The user token expire after 60 seconds. From what I understand, the user session token should not be stored into your database but the store session should since it's the token you need when your app call Shopify API on WebHook events.
I think the user token should be an online access token and the store token should be an offline access token. Online token expires. Offline token don't. So, from my understanding, we should have a way to generate and handle user/shop session tokens but I don't see it in the actual @shopify/shopify-api documentation. |
Hey folks! Thanks for raising this. This is a know issue we're currently working on. Sorry we don't have an immediate solution to suggest, but hopefully this bug will be gone soon. |
Thanks for the reply, @thecodepixi. :) Are you referring to #169 when you're saying that you're currently working on it? |
Thanks very much @arsnl for the helpful information and to @thecodepixi for your reply. It would be good to understand which thread to monitor so that we get updated on any potential fix. Can I ask a very quick follow up question related to the quote above:
In my server.js
Now I'm just trying to understand the docs which note:
My question:
Thanks! |
Hi @g-hamilton! :) I don't know if your app is embedded or not. But, if your app is embedded (inside an iframe in the Shopify Admin), your cookies are always third-party cookies since the url of your app don't match the url of the browser. If your app is not embedded, it should. It's better for the UX. Because of that, it's not recommended to use cookies with your app. From what I see, the way to make it work correctly is to;
|
Hi, |
Ok. As you see, the issue is already acknowledged and a fix is in progress with this PR #169 We hope it's gonna be fixed and release soon.
"How" they work is really depend on you since they are only handler functions you define yourself on your project. Basically, you can do anything inside these functions, but you have to respect their signature (what they accept, what they return). For example, to fix the issue described here and avoid useless network calls, I did a utility function to detect if the session was a store or a client session. If it's a store session, I use Redis for all three handlers ( You can learn more about |
I'm also seeing the same. Further more, the session data changes. Sometimes it's like this:
And other times it looks like this:
What's causing this? |
FWIW, #169 didn't fix this issue above. |
Hey folks! So, the reason you're seeing two sessions is that we use one 1st party cookie-based session for OAuth, which then gets converted to a JWT-based session that can be used in an embedded app. Previously, we were setting the OAuth session to expire a little bit after the process is completed, so that you could still call With our upcoming v2, we're aiming to fix that by returning the session in the OAuth callback and deleting the OAuth session right away for the app. This is the PR that implements that: #217. Hope this helps! |
When will this be fixed? |
how does one check release timelines? (I.e when is v2 going to be released?) Is it in the repo somewhere? |
Does anyone have a proposed workaround or solution? |
Any updates @paulomarg @arsnl @thecodepixi ? Would love to get this fixed! |
Hey @staadecker ! :) Sadly, I cannot help you with that. I've stopped using shopify-node-api since it was not stable enough for my production requirements. This still not fixed bug is a good example. I was finding myself in a situation where I was blocked by bugs that I was trying to fix on the solution supposed to help me develop a Shopify app faster. This was really counter productive so I've just decided to drop it and call the API directly. |
Ok thank you! I might have to do the same, unfortunately. |
Question: does anyone know if the If the answer is "no, this is only for 'online' session management" then why pass the |
Yes, offline tokens are also stored using storeCallback. It works the same as online tokens in that aspect. |
Ok.. so if we're doing something special w/ offline tokens (like putting them in a place where a background serverless service worker would need to access them) we should be doing that persistence, based on the the |
Whatever your 'persist Session / token in your database' logic is, it should live in storeCallback, yep! |
Thanks! |
@RavenHursT it sounds like you're thinking about offline tokens in the same way we do where they're not really "sessions" but rather "stores" which aren't saved in a session DB, but instead our application DB which can be read by other services running jobs in the background or on webhooks etc? If so, are you doing something like this, and how do you read it appropriately? Shopify.Context.initialize({
...
SESSION_STORAGE: new Shopify.Session.CustomSessionStorage(
async function storeCallback(session) {
if (session.isOnline) {
// `sessionDB` is a DB designed for v. fast read / writes (potentially in exchange for reduced durability), e.g. redis
return await sessionDB.sessions.save(session.id, session);
}
// `appDB` is a DB designed with stronger durability guarantees, e.g. PostGres, MySQL or MongoDB etc.
return await appDB.stores.upsert({ shop: session.shop, accessToken: session.accessToken });
},
async function loadCallback(id) {
// Where do you look up the 'session'?
},
async function deleteCallback(id) {
// Where do you look up the 'session'?
}
)
}); |
@richardscarrott correct. What you've got there, is similar to what we're doing, storing the "offline" tokens, on app install, into a postGres DB.. Then, for background processes (in our case, AWS Lambdas that run a few times each hour) we just query the PostGres DB as normal, based on the shop we're operating on, and use that offline token to interact w/ the Shopify API... |
@RavenHursT Thanks for the response. Do you additionally store the "online" uuid session in your postgres DB too; i.e. the one mentioned here #224 (comment) which doesn't have an access token associated with it:
|
@richardscarrott yeah.. We dump everything into redis, keyed on |
This issue is stale because it has been open for 90 days with no activity. It will be closed if no further action occurs in 14 days. |
We are closing this issue because it has been inactive for a few months. If you still encounter this issue with the latest stable version, please reopen using the issue template. You can also contribute directly by submitting a pull request– see the CONTRIBUTING.md file for guidelines Thank you! |
I'm not 100% sure this is a bug, but it seems to be unexpected behaviour so I need to ask...
I built a Node shopify app using the shopify CLI (recent version).
In my server.js file, I'm initialising the Shopify context to use custom session storage, like so:
I used the guide to define the 3 required callback methods. I'm using Firebase for my custom storage solution, so my code looks like this:
What I would expect to see when a user installs the app is a single session object being stored in the DB.
What I actually see is 2 session objects being stored, each with a different session ID.
Here is the relevant portion of my logs from a single app install on my development store at the point where the custom session methods are being executed:
Note:
session.accessToken
andsession.onlineAccessInfo.associatedUser.session
, but differentsession.id
andsession.expires
value.So my questions:
storeCallback
firing twice, with 2 different session IDs even though as a user, I've only started one session from one app install?session.expires
to decide whether to send the user back into the oauth flow (I think that is the correct implementation but stop me if I'm wrong). With 2 different sessions for the same user, which one should I inspect? I've tested locally and ended up with 4 session objects from the same app/install, which is really odd! I'm guessing that if I answer question 1, question 2 becomes irrelevant.Thanks in advance for the help :)
The text was updated successfully, but these errors were encountered: