2

Using dockerized Ory Kratos and Angular (www folder hosted via nginx to be able to modify headers) on localhost and trying to execute

const headers = {
   Accept: 'application/json',
};
fetch('http://127.0.0.1:4433/self-service/registration/browser', {
  method: 'GET', 
  headers,
  redirect: 'follow',
  credentials: 'include',
})
.then((r) => console.log(r))
.catch((f) => console.log(f));

leads to

Access to fetch at 'http://127.0.0.1:8100/auth/register?flow=b35c3f9a-5592-4121-80b9-87503c38e1d3' (redirected from 'http://127.0.0.1:4433/self-service/registration/browser') from origin 'http://127.0.0.1:8100' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'http://127.0.0.1:8100' that is not equal to the supplied origin. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

http://127.0.0.1:4433/self-service/registration/browser redirects to http://127.0.0.1:8100/custompath/register?flow=[some-flow-id] via a 302 HTTP response. The browser tries to resolve the redirect and throws the error mentioned above.

Origin and allowed origin are the same - so how can that error happen? I already found this answer on stackoverflow: https://stackoverflow.com/a/62320912/14345380 if that's helpful.

Chrome version 87.0.4280.88

Edit #1 Network tab output can be seen here

Edit #2 To be able to resolve the issue yourself I set up a little repository: Find it here

Edit #3 Thanks for the hint from pandamakes. The test repo is not running on :8100 but on 4200 (Switched from ionic project to angular project).

Edit #4 I started another discussion at the ory/kratos project origin here. The Ory Team implemented a SDK which we can use instead of plain fetch requests.

tmi
  • 21
  • 5
  • But it is redirected via :4433 – mplungjan Dec 16 '20 at 07:58
  • I already tried to allow :4433, then both (:8100 and :4433), which is not supported. – tmi Dec 16 '20 at 08:00
  • does `http://127.0.0.1:8100` return the correct cors header? (show dev tool output if possible?) – pandamakes Dec 16 '20 at 08:01
  • Adapted the question to your needs. – tmi Dec 16 '20 at 08:08
  • and the web frontend is hosted on `127.0.0.1:8100` ? – pandamakes Dec 16 '20 at 08:33
  • I will also need to double check, but request `origin: null` looks sus. I will have to take a deeper look – pandamakes Dec 16 '20 at 08:35
  • The frontend is hosted via an nginx docker container on 127.0.0.1:8100. origin: null may be because of the redirection? – tmi Dec 16 '20 at 08:44
  • if the port is not the same, then i believe that CORS triggers... in other words : `different port = different origin`, even though host are same. – JoSSte Dec 16 '20 at 11:24
  • But even the ports are the same as it can be seen in the error message above. Also https://sequoia.makes.software/session-management-with-microservices/#i-thought-cookies-couldn-39-t-be-shared- suggests that different ports do not trigger CORS. – tmi Dec 16 '20 at 12:38
  • I cloned the repo, but couldn't find a reference to port 8100. I see nginx is listening on 4200 and kratos running on 4433? (edit: judging from `docker-compose.yml` alone) – pandamakes Dec 16 '20 at 13:04
  • it may be possible that CORS request cannot be redirected to a different host: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSExternalRedirectNotAllowed – pandamakes Dec 16 '20 at 13:12
  • Sorry therefore. I had the original repo running with ionic which is served at 8100. Angular is served on 4200. shouldn't make a big difference though. In the browser you can (like you already figured out by reading the docker-compose file) find it here: http://localhost:4200 – tmi Dec 16 '20 at 13:35
  • I updated my question the 4th time => I think the SDK intends to be able to achieve it - so I really hope it's possible. – tmi Dec 16 '20 at 13:43
  • @tmi I understand what you are saying re: ports. I am trying something, but in the mean time, if you have time, as crazy as it sounds, try to remove https://github.com/TMInnovations/testorykratos/blob/main/docker/default.conf#L12 (yes, remove the cors header) and let me know how it goes? – pandamakes Dec 16 '20 at 13:46
  • I only use a reverse proxy to add this header. Without it the error is: Access to XMLHttpRequest at 'http://localhost:4200/?flow=031ec155-a18d-4719-a1b4-1cc78f9cba63' (redirected from 'http://localhost:4433/self-service/registration/browser') from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. – tmi Dec 16 '20 at 13:59
  • With '*' it's not throwing an error :-O But it's also not delivering the csrf_token cookie. – tmi Dec 16 '20 at 14:08
  • I just took a look at https://www.ory.sh/kratos/docs/reference/api/#initialize-registration-flow-for-browsers , I wonder if this endpoint is meant for your application hyper link to the url, rather than use fetch? – pandamakes Dec 16 '20 at 14:15
  • As my application should be a SPA I don't really want to reload the page. Currently I'm using (in my project and the min repo) the SDK provded by ory/kratos (which most probably also uses fetch). – tmi Dec 16 '20 at 14:24
  • do you have a repo for ory/drato sdk? or just use the sdk? SPA is not my forte. I typically use passportjs or openid for user auth – pandamakes Dec 16 '20 at 14:56
  • I'm not a developer of ory (unfortunately :-P). The sdk can be found here: https://www.npmjs.com/package/@oryd/kratos-client. And the sdk is generated automatically as you can read here: https://github.com/ory/kratos/blob/8e7f9f5ec3ac6f5675584974e8d189247b539634/docs/docs/sdk.md – tmi Dec 16 '20 at 15:45

2 Answers2

0

One thing is simply add no-cors to the request.

mode: 'no-cors'

Also, you say you have Access-Control-Allow-Origin header set did you also set Access-Control-Allow-Credentials: true , since you are fetching with credentials: "include".

Lastly setting credentials: "include" origin can not be a localhost or 127.0.0.1 or it will return false and cause a cors error, so either, set credentials to same-site or omit or get yourself a domain name.

norcal johnny
  • 2,050
  • 2
  • 13
  • 17
  • Thank you for the answer. no-cors will deliver an opaque response, which is not satisfying for a registration request that should respond with the flowid (look at rest-api doc here: https://www.ory.sh/kratos/docs/reference/api#initialize-registration-flow-for-browsers). Tried to add the Access-Control-Allow-Credentials: true header but that dindn't have any effect. Setting the credentials to same-origin has no effect. Same error message, same for omit. So I think it's not related to the credentials header. Same happens if the credentials header is not adjusted in the header block. – tmi Dec 16 '20 at 12:35
  • I already have a domain. But I want myself and other contributing developers to be able to work on localhost. If there's no other solution, we maybe will switch to online development (not very cool). – tmi Dec 16 '20 at 12:46
0

I ... think I got it...

The 302 redirection works, but when the fetch requests follows the redirection, it now attempts at fetching a non-cors resource. In this event, it will not attach an Origin request header (since it is a non CORS request).

When the response arrives, the browser will compare access-control-allow-origin header, if any exist, to the origin of the request. If the response header exists, and is not *, it must match the origin header of the request.

So solve your issue, you will want to remove the access-control-allow-origin in your nginx setup, or set it to *

min repro: https://github.com/xgui3783/cors-min-repro

pandamakes
  • 571
  • 3
  • 8
  • Thank you! Omiting it in tmy repo did not work but setting it to * allowed it to not throw an error. However the csrf_token cookie is not delivered when doing so. Also the flow_id cannot be grabbed from the response as I see. In your repo I don't see cookies set. So: Yes it's working, but I can't clarify it with cookies (which are needed for the registration process at ory/kratos). – tmi Dec 16 '20 at 14:17