CORS issues with Ueberauth + Okta for Nuxt/Phoenix app

Summary
I am seeing a “CORS header ‘Access-Control-Allow-Origin’ missing” error for a request to Okta’s authorize endpoint despite having configured Okta with appropriate Trusted Origins.

Details
Frontend = NuxtJS (VueJS) running in node at localhost:3000
Backend = Phoenix running at localhost:4000

I have listed localhost:3000 and localhost:4000 as Trusted Origins for CORS and Redirect in Okta.

I did run the test in the “Enable CORS” section of the Okta doc and it worked fine.

I did try this in Firefox, Chrome and Safari with the same results in each.

The process is:

  1. The Javascript application issues GET /api/login and the Phoenix app responds with a 302 redirect to /auth/okta. Works fine.

  2. The Javascript application then requests GET /auth/okta as directed and the Phoenix app (by way of Ueberauth Okta responds with a 302 redirect to the Okta /authorize endpoint (works fine):

    https ://dev-7777777.okta.com/oauth2/v1/authorize?client_id=xyz&nonce=zyx&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Fauth%2Fokta%2Fcallback&response_type=code&scope=openid+email+profile&state=state-07F40B06C81E687853980FB5

  3. The Javascript application then issues a pre-flight (HTTP OPTIONS) request to Okta:

    OPTIONS /oauth2/v1/authorize?client_id=xyz&nonce=zyx&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Fauth%2Fokta%2Fcallback&response_type=code&scope=openid+email+profile&state=state-07F40B06C81E687853980FB5 HTTP/2
    Host: dev-777777.okta.com
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:82.0) Gecko/20100101 Firefox/82.0
    Accept: /
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate, br
    Access-Control-Request-Method: GET
    Access-Control-Request-Headers: access-control-allow-origin
    Referer: http://localhost:3000/login
    Origin: http://localhost:3000
    Connection: keep-alive

to which Okta responds:

HTTP/2 200 OK
date: Mon, 09 Nov 2020 17:03:44 GMT
content-length: 0
server: nginx
public-key-pins-report-only: pin-sha256="r5EfzZxQVvQpKo3AgYRaT7X2bDO/kj3ACwmxfdT2zt8="; pin-sha256="MaqlcUgk2mvY/RFSGeSwBRkI+rZ6/dxe/DuQfBT/vnQ="; pin-sha256="72G5IEvDEWn+EThf3qjR7/bQSWaS2ZSLqolhnO6iyJI="; pin-sha256="rrV6CLCCvqnk89gWibYT0JO6fNQ8cCit7GGoiVTjCOg="; max-age=60; report-uri="https://okta.report-uri.com/r/default/hpkp/reportOnly"
x-okta-request-id: X6l2cMtA@8GfUasz6CloCAAAAyM
x-xss-protection: 0
p3p: CP="HONK"
x-rate-limit-limit: 10000
x-rate-limit-remaining: 9999
x-rate-limit-reset: 1604941484
content-security-policy-report-only: default-src 'self' *.oktacdn.com dev-7777777.okta.com; connect-src 'self' *.oktacdn.com *.mixpanel.com *.mapbox.com app.pendo.io data.pendo.io pendo-static-5634101834153984.storage.googleapis.com dev-4252537.okta.com dev-7777777-admin.okta.com https://oinmanager.okta.com data:; script-src 'unsafe-inline' 'unsafe-eval' 'self' *.oktacdn.com; style-src 'unsafe-inline' 'self' *.oktacdn.com app.pendo.io cdn.pendo.io pendo-static-5634101834153984.storage.googleapis.com; frame-src 'self' login.okta.com dev-7777777.okta.com dev-4252537-admin.okta.com; img-src 'self' *.oktacdn.com dev-7777777.okta.com *.tiles.mapbox.com *.mapbox.com app.pendo.io data.pendo.io cdn.pendo.io pendo-static-5634101834153984.storage.googleapis.com data: blob:; font-src data: 'self' *.oktacdn.com fonts.gstatic.com; report-uri https://okta.report-uri.com/r/d/csp/reportOnly; report-to csp-report
report-to: {"group":"csp-report","max_age":31536000,"endpoints":[{"url":"https://okta.report-uri.com/r/d/csp/reportOnly"}],"include_subdomains":true}
cache-control: no-cache, no-store
pragma: no-cache
expires: 0
x-frame-options: SAMEORIGIN
allow: GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH
strict-transport-security: max-age=315360000; includeSubDomains
x-robots-tag: none
set-cookie: sid=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
set-cookie: JSESSIONID=0DC93A2E22DE1B291C1A7F5F569F2810; Path=/; Secure; HttpOnly
set-cookie: DT=DI0VsaaIxY3QseA9wHcJRySiA;Version=1;Path=/;Max-Age=63072000;Secure;Expires=Wed, 09 Nov 2022 17:03:44 GMT;SameSite=None
set-cookie: sid=""; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/
X-Firefox-Spdy: h2

(Note that there are no CORS headers in the response.)

  1. And then I get the dreaded error:

    Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https ://dev-7777777.okta.com/oauth2/v1/authorize?client_id=xyz&nonce=zyx&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Fauth%2Fokta%2Fcallback&response_type=code&scope=openid+email+profile&state=state-07F40B06C81E687853980FB5. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

which is, I believe, because there are no CORS headers in the pre-flight response so the browser denies the Javascript application (whose origin is localhost:3000) from requesting /authorize from Okta’s domain.

Am I using ueberauth_okta incorrectly, or is there some CORS config I need to do in Phoenix, or is this an Okta problem?

Thank you for any help.

For others who might find their way here some day…the answer is that most of the Identity and Access Management services (Auth0, Okta, etc.) will only accept a browser request (not a Javascript request) to their /authorize endpoint.

In my case, I started the whole login process from a Javascript function, so Javascript was handing all of the HTTP interactions with the Phoenix server, including the redirect to Okta.

Simply changing my Nuxt app to do a normal browser location change (by just using a href on a login link instead of calling a Javascript function) made it work as expected.

Well that was painful…

2 Likes