{
"errors": [
{
"message": "Authorization failed",
"context": "Unable to determine the authenticated user or integration. Check that cookies are being passed through if using session authentication.",
"type": "NoPermissionError",
"details": null,
"property": null,
"help": null,
"code": null,
"id": "e6518360-4a0f-11ed-b437-dba7f71d3857",
"ghostErrorCode": null
}
]
}
The 403 is expected, nothing to worry about. When you access the admin app it makes a request to the API to get the logged-in staff user details, if you’re not logged in the API responds with a 403 and the admin app knows to show the login screen.
It works on this domain: blog.domain.com/blog/ghost
But now we have encountered another issue.
We use Cloudflare’s worker for every access of the domain.com/blog* route.
We fetch the subdomain blog.domain.com/blog page and show it on the root domain domain.com/blog
The code of the worker.
const GHOST_CONFIG = {
SUBDOMAIN: "blog.domain.com",
ROOT: "domain.com",
BLOG_PATH: "blog"
}
// Function that processes requests to the URL the worker is at
async function handleRequest(request) {
// Grab the request URL's pathname, we'll use it later
const url = new URL(request.url);
const targetPath = url.pathname;
let response = await fetch(`https://${GHOST_CONFIG.SUBDOMAIN}${targetPath}`);
console.log(response);
// Ghost loads assets like JS and CSS from 3 subdirectories
// We don't need to change these requests at all
// So if we're getting stuff from those subdirectories,
// we return the response of the fetch request from above
// immediately.
if (
targetPath.includes(`/${GHOST_CONFIG.BLOG_PATH}/favicon.png`) ||
targetPath.includes(`/${GHOST_CONFIG.BLOG_PATH}/sitemap.xsl`) ||
targetPath.includes(`/${GHOST_CONFIG.BLOG_PATH}/assets/`) ||
targetPath.includes(`/${GHOST_CONFIG.BLOG_PATH}/public/`) ||
targetPath.includes(`/${GHOST_CONFIG.BLOG_PATH}/content/`)
) {
return response
}
// In other cases - which will usually be pages of the
// Ghost blog - we want to find any reference to our subdomain
// and replace it with our root domain.
// This is so that things like our canonical URLs and links are
// set up correctly, so we NEVER see our subdirectory in the code.
// First we get the body of the response from above
let body = await response.text()
// Then we search in the body to replace the subdomain everywhere
// with the root domain.
body = body.split(GHOST_CONFIG.SUBDOMAIN).join(GHOST_CONFIG.ROOT)
response = new Response(body, response)
return response
}
{
"errors": [
{
"message": "Authorization failed",
"context": "Unable to determine the authenticated user or integration. Check that cookies are being passed through if using session authentication.",
"type": "NoPermissionError",
"details": null,
"property": null,
"help": null,
"code": null,
"id": "63754bb0-4a1a-11ed-b437-dba7f71d3857",
"ghostErrorCode": null
}
]
}
So the question is — is the problem because this setup forges the request and cookies are not passed properly, resulting in auth error?
Do you have the url config in Ghost set to domain.com/blog? If the url doesn’t match where you’re actually serving the site you’ll run into problems due to domain mismatches. Configuring the site properly like that will also mean you don’t need to do any rewrites in your workers and you’re closer to the supported way of proxying a subdirectory site.
The url of the Ghost is set to https://blog.domain.com/blog.
Correct, the URL does not match because we intend users to open domain.com/blog. We want it to be specifically on the root domain for SEO purposes.
Configuring the site properly like that will also mean you don’t need to do any rewrites in your workers, and you’re closer to the supported way of proxying a subdirectory site.
I think I understand your point. We have such a setup because we are hosted on notion pages on our root domain, domain.com, so we use 2 Cloudflare workers for domain.com/* (notion pages) and domain.com/blog* (Ghost).
I’ll try to do it under one worker with the root domain.
In your config, set url to https://domain.com/blog
Since you’re planning on sharing https://domain.com/blog with everyone, Ghost has to be configured like this. Otherwise, some of the links that show up on the page will also point to the wrong place
[optional] update admin.url to https://blog.domain.com/blog. Then, have your staff access the admin via https://blog.domain.com/blog/ghost/. More information on the admin URL: Configuration - Adapt your publication to suit your needs
The CORS policies have changed quite a bit since I last looked into them, so I’m not sure. I don’t think you can change the CORS policies, but I do think they’re designed to allow proper communication if you have between a separate frontend and backend, if you’ve properly configured them