koa-shopify-auth
koa-shopify-auth copied to clipboard
[koa-shopify-auth] - Cookies and redirect not working on serverless functions (like firebase)
Overview
I'm trying to host the Koa app on Firebase Cloud Functions and I'm having two problems.
Cookie issue
Firebase functions only allows one cookie, named __session
. Every other cookie gets stripped out. (reference)
koa-shopify-auth
package relies upon cookies by settings them with the Koa api like ctx.cookies.set(TEST_COOKIE_NAME, '1');
etc. So this doesn't work because the cookie name is not __session
.
Suggested Solution: Instead of setting/getting cookies directly from ctx.cookies
, we can first try to use ctx.session
. If there is no session
, then fallback to setting cookies directly.
In my case, I've set up the koa-session
middleware to use the cookie key __session
, so the above solution will work just fine with something like: ctx.session[TOP_LEVEL_OAUTH_COOKIE_NAME] = '1';
Redirect issue
My cloud function's endpoint is https://us-central1-my-project-id.cloudfunctions.net/mykoaapp
.
I've set up the URL rewrites so the above function that is my koa app, is available at (and also whitelisted in the Shopify partner dashboard):
https://my-project-id.firebaseapp.com/api
Assuming the prefix
is working (currently it is broken Shopify/quilt#1148), the redirect is set to ${prefix}/auth?shop=${shop}
The problem is that the redirect is using a relative path from the root domain. In my case, I need the redirect set to https://my-project-id.firebaseapp.com/api/${prefix}/auth?shop=${shop}
, otherwise, as per the current behavior, the user gets to the 404-page in my case, because the redirected location gets set to https://my-project-id.firebaseapp.com/${prefix}/auth?shop=${shop}
,
Suggested Solution:
OAuthStartOptions
should take an additional option something like APP_ROOT_URL
.
And whenever we redirect the user to any URL, we should prepend the APP_ROOT_URL
if it exists.
Something like:
`${APP_ROOT_URL || ''}${prefix}/auth?shop=${shop}`,
...
Type
- [ ] New feature
- [x] Changes to existing features
Motivation
What inspired this feature request? What problems were you facing, or what else makes you think this should be in
quilt
?
I encountered these problems after following this tutorial. The tutorial part was fine, but when I moved to the deployment part, it very just painful as I wasn't aware of these serverless limitations earlier.
While I know that these are not the issues with this package itself and can be avoided if I deploy the app on a platform like Heroku. But supporting serverless environments by adding a bit more flexibility to the package is worthwhile I believe because more and more apps are built using serverless functions these days.
...
Scope
-
Is this issue related to a specific package?
- [x] Tag it with the
Package: koa-shopify-auth
label.
- [x] Tag it with the
Checklist
- [x] Please delete the labels section before submitting your issue
- [x] I have described this issue in a way that is actionable (if possible)
@tylerball, @TheMallen - could you offer your expertise here, please?
@husseyexplores These seem like good changes. Feel free to open a PR but if not I'll look into opening one soon.
I can confirm the url redirect issue. wow until today i thought i was crazy with all the issues i was hitting.
btw i think that first issue is invalid in its description. My test cookie gets set for the response but you cannot read incoming request cookies without '__session'. Pretty sure there is a related issue though with koa-session that makes it cause some issue in this setup.
I put together a snippet that seems to solve the issue but I need to integrate it into koa-shopify-auth which is why im here now haha.
` { FirestoreStore } = require("koa-session-firestore");
const COOKIE_CONFIG = { maxAge: 86400000 };
var KoaFirebaseSession = { set: async (ctx, key, val) => { var ourSessionKey = ctx.cookies.get("__session"); if(!ourSessionKey) { ourSessionKey = uuidv4(); ctx.cookies.set("__session", ourSessionKey); } await FirestoreStore.set(ourSessionKey, { [key]: val, "_expire": Date.now() + COOKIE_CONFIG.maxAge, "_maxAge": COOKIE_CONFIG.maxAge }); }, get: async (ctx, key=null) => { var ourSessionKey = ctx.cookies.get("__session"); if(ourSessionKey) { var sessionData = await FirestoreStore.get(ourSessionKey, COOKIE_CONFIG.maxAge); if(key && sessionData && sessionData[key]) { return sessionData[key]; } else if(sessionData) { return sessionData; } } return {}; } }`
@tylerball I tried to fix it but I couldn't figure out what to do regarding create-enable-cookies.ts
Will replacing shopify.cookies_persist=true
to __session=true
work? I think this doing this will certainly break the koa-session
middleware because session values are cryptic, and overriding session cookie like this will invalidate/reset the session.
For the time being, I just set up my own express server with the auth logic. And if the cookies are not enabled, I prompt the user to enable the cookies then try again. The app I'm building was only for a couple of merchants, so I wasn't much of a problem. But if there is any solution for this, that'd be very awesome. Will reduce a whole lot of boilerplate for other fellow devs.
@Sotacan Yes indeed, the cookie gets set for the outgoing requests. But any incoming request will only contain __session
cookie. So in this context, this clearly doesn't work because if we can't even read the cookies that we set earlier, what's the point then?
As for your snippet, it won't work either just because of the same 2 issues I've described above. At the end of the day, you're dealing with cookies and cloud function limitations. Doesn't matter if you use any library for this or not.
Has anyone found a solution for the redirect issue? I'm still struggling.
Note that this repo is no longer maintained and this issue will not be reviewed. Prefer the official JavaScript API library. If you still want to use Koa, see simple-koa-shopify-auth for a potential community solution.