Closed valorloff closed 1 year ago
Hi!
I got offline sessionId by
shopify.session.getOfflineId(req.query.shop);
and now I can make requests
is it correct way?
Unfortunately In production
shopify.session.getOfflineId(req.query.shop);
don't works.
Please, what is correct way to make auth requests during incoming requests from App proxy ?
I am also getting this exact same behavior with Shopify Flow triggers. Even after scaffolding a stock extension from the shopify-cli generators. All inbound requests loose the shop parameter and go to /auth please help!
in shopify apps docs specified proxy URL:
GET /apps/awesome_reviews/extra/path/components?extra=1&extra=2 HTTP/1.1
Host: shop-domain.com
Cookie: csrftoken=01234456789abcdef0123456789abcde;
_session_id=1234456789abcdef0123456789abcdef;
_secure_session_id=234456789abcdef0123456789abcdef0
i see there _session_id, possible this is desired sessionId, needed for
sqliteSessionStorage.loadSession(sessionId);
?
if you try
shopify.auth.callback({
rawRequest: req,
rawResponse: res,
});
i get
CookieNotFound [Error]: Cannot complete OAuth process. Could not find an OAuth cookie for shop
due they are disabled in app proxy request! So, please, how to make authenticated request from app proxy?
I am experiencing the same issue. When I hardcode the sessionId
inside validate-authenticated-session.js
in the shopify.validateAuthenticatedSession()
middleware I get the correct expected behavior.
I created my app one day ago with the most updated node app in the shopify-cli
and am following the documentation. I am making a request to my app via postman to a custom api route behind the app.use('/api/*, shopify.validateAuthenticatedSession())
middleware. I installed my app on a test store and successfully created a session via MongoDBSessionStorage
and saved the session to the database.
Inside validateAuthenticatedSession()
there's a try / catch
block calling api.session.getCurrentId()
with the req, res, isOnline
as input parameters. This was not working for me so I experimented with hardcoding my test store's sessionId
to troubleshoot and afterwards it worked properly. I'm not sure if this is an issue with getCurrentId()
or the MongoDBSessionStorage
library.
The below try / catch
block works as intended (hardcoded) but does not work out-of-the-box when making request from postman with this url:
GET {{ shopify_provided_ngrok_url }}/api/{{ custom_route }}?shop=my-shop.myshopify.com
try {
sessionId = await api.session.getCurrentId({
isOnline: config.useOnlineTokens,
rawRequest: req,
rawResponse: res
});
/**
* Below line hardcoded in to troubleshoot the issue
*/
sessionId = 'offline_my-shop.myshopify.com'
} catch (error) {
await config.logger.error(`Error when loading session from storage: ${error}`);
await handleSessionError(req, res, error);
return undefined;
}
The above edit got my app working as intended and I'm able to continue local development via postman, but it is not a fix. My session storage config is set up like the below. Do I need to define a handler for getting the current id?
const shopify = shopifyApp({
api: {
apiVersion: LATEST_API_VERSION,
restResources,
billing: undefined, // or replace with billingConfig above to enable example billing
},
...
sessionStorage: new MongoDBSessionStorage(
'mongodb_connection_string',
'collection_name',
),
});
from appProxy request you are getting shop domain name, then use it in
const sessions = await mongoSessionStorage.findSessionsByShop(req.query.shop);
for getting session object
did I understand you correctly?
It looks like the most recent version of the node app included in the shopify-cli
already has some middleware for parsing out the shop parameter, so I wasn't using that line you mentioned (though maybe I should be?).
Out of the box the node app template has this line
app.use("/api/*", shopify.validateAuthenticatedSession());
And I just set up a router for */api/health
to see if my external requests were getting authenticated correctly with that middleware function, and they were not. So I dug into the shopify.validateAuthenticatedSession()
library function in the @shopify/shopify-app-express
package. It looks like the line
sessionId = await api.session.getCurrentId({
isOnline: config.useOnlineTokens,
rawRequest: req,
rawResponse: res
});
is not reading my shop parameter from the req correctly (sessionId
was returning null
), so I hardcoded it and things worked. I could have something wrong as I'm somewhat new to developing shopify apps.
This topic about "authenticated request from proxy", and i come to a conclusion, that in request object, coming from proxy, there is no sessionId, but there is a shop name, by which we get session object
Understood, apologies for the spam.
Hi @valorloff,
Could you let me know if you managed to get this fixed?
I am facing similar issue. But I think for a request to be passed through app proxy, it's endpoint has to start with "/apps/*"
but you are using /api/*, did it work?
@dongido001, the entry point can be any, do not confuse with the app proxy settings.
And yes, this fixed by mongoSessionStorage.findSessionsByShop
, as i have already explained above
here is my setting:
This is the endpoint the app proxy is targeted to, which is working:
But when I try to access the proxy, it does not work:
I am so confused as to what I am doing wrong
you messed up everything, you need to specify the correct url in the fetch:
fetch(
/apps/proxy/api/proxy_shopify?......`
thanks you @valorloff
Hey @brdsmth I am having same issue you had:
I am having problems with finding the way to avoid this /* so I can return my own response. Maybe it's a very basic concept but can't find the solution. How did you solve your proxy authetication in the end? Thank you for your help!
@brdsmth you need use the /api endpoint, the request come to, which is contain shop name, that is being used for session_id, that is being used for getting session from storage
Hi @valorloff Thank you for your help. If I do that then I receive a response saying I am missing the Authorization header. Am I missing something else? the validateAuthentication already is implemented with all the process inside the middleware. I cannot choose to get the Id by findSessionsByShop....Obviusly I might be missing a step
@Paula-Alohas. are you using the latest CLI template (3.0)?
Then you need to move the proxy endpoints to the top. make sure it above "app.get(shopify.config.auth.path, shopify.auth.begin());". that's if I understand you correctly
@Paula-Alohas I fixed this by implementing a middleware function to check for session details in mongodb
in web/index.js
I replaced
// All endpoints after this point will require an active session
// app.use("/api/*", shopify.validateAuthenticatedSession());
app.use('/api/*', checkForSession)
with my middleware function being below
export const checkForSession = async function (req, res, next) {
const session = await db.collection('shopify_sessions').findOne({ /** whatever index **/ })
res.locals.shopify = { session: {} }
res.locals.shopify.session = session
next()
}
You may need to experiment with what you index the db with - for instance you could pass shop name as a query param and get it from req
or pass something else that would help you find session in db. If you're making request from inside embedded app you may need to parse the referer
or the shop name straight from the url and use that to index db. But this middleware strategy is working fine for me now
Thank you so much! I will definitely try this solution. Sounds like the way to go for me
As far as I understand, request from app proxy don't contain Authorization header at all, only shop name. Authorization header you can receive only from app request, not from online store.
@brdsmth
Tried your middleware solution and it partially fixed the issue for me :(. I am getting [shopify-app/ERROR] ensureInstalledOnShop did not receive a shop query argument | {shop: undefined} . Any thoughts on this would be appreciated
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. This probably means that it is not reproducible or it has been fixed in a newer version. If it’s an enhancement and hasn’t been taken on since it was submitted, then it seems other issues have taken priority.
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!
Issue summary
Hi! Thanks for the abolition customSessionStorage and switching to shop name identification! But after migrate to useAppQuery and api-js-V.6, it is not clear where to get the sessionId for making requests, coming from the App proxy.
i get
[shopify-api/ERROR] Missing Authorization header, was the request made with authenticatedFetch? | {isOnline: false}
Expected behavior
I was sure that the incoming request headers should contain the necessary session object for requests
Steps to reproduce the problem
When requests are received to app proxy url, request data don't contain valid authenticated data, that is contained when a request is received from internal useAppQuery (with authanticatedFetch) request
Question
How can valid session data from app proxy be obtained?