403 forbidden errors when deploying JSS apps to Sitecore
Getting started with Headless development using Sitecore Headless SDKs and Docker are very easy. All you need to do is to
- Create a Headless app using command "npx create-sitecore-jss@ver20" following the instructions here
- When you want to connect with a real Sitecore instance running on Docker, just use one of the docker-examples then connect following the examples here (It is a remote Sitecore instance in this case)
The Issue
When deploying the JSS app to Sitecore using the command
jss deploy app -c -d
You may get the following errors:
Wrote sitecore\package\sitecore-jss-app.xxxxxxxxx.manifest.zip
Sending package sitecore\package\sitecore-jss-app.xxxxxxxxx.manifest.zip to https://cm.dockerexamples.localhost/sitecore/api/jss/import...
Unexpected response from import service:
Status message: Forbidden
Status: 403
Troubleshooting
- Set "debugSecurity" to true in "\App_Config\Include\zzz\sitecore-jss-app.deploysecret.config" file that is deployed to your Sitecore instance.
- Then run the jss deploy app command again with "--debugSecurity" like below
jss deploy app -c -d --debugSecurity
You can then check the logs in jss deploy app command comparing to the logs from the Sitecore instance. You will see the difference here is caused by "Deployment security factors" in jss and "Server-side security factors" in Sitecore CM have the URLs in https vs http.
This is a security feature and the reason to our issue being that instances in docker are exposed via traefik on https when accessed from host machine, but within docker the request is received on http.
The fix is to make the "security factors" match from the both sides.
Solutions
There are 2 solutions to this. One is more hacky but quicker than the other one.
Solution 1: The hacky and quick one. Change the npm package so it is requesting on https but generates the security headers in http.
- In your JSS app
- Find file "\node_modules\@sitecore-jss\sitecore-jss-dev-tools\dist\cjs\package-deploy.js",
- Find the 2 lines that start with "const factors ="
- Append ".replace("https","http")" after "options.importServiceUrl"
Solution 2: The more proper one. Enable http on traefik for CM in docker setup.
- In your Sitecore "docker-compose.override.yml" file
- Add below to cm, then restart docker containers
ports:
- 80:80
- In the JSS app, scjssconfig.json file
- Change the "deployUrl" to http://localhost/sitecore/api/jss/import
The solution requires port 80 not being used in your local machine. Which should be the case if you have worked with Sitecore in docker for a while locally or planning to do so. If not, using a different port number is actually very tricky and can easily go down a rabbit hole. Some readings here:
Which I'd rather not to because the point of using Sitecore with docker is to allow quick and efficient ways to set up local environments and to start development right away.
Notes: All above are based on Sitecore 10.2 XP0 and Sitecore JSS NextJS 20.1.3