docs icon indicating copy to clipboard operation
docs copied to clipboard

Express quick start example fails due to incorrect whoami request port

Open ammanvedi opened this issue 3 years ago • 15 comments

Preflight checklist

Describe the bug

https://www.ory.sh/docs/guides/protect-page-login/expressjs#require-login-to-access-the-home-page

.toSession seems to want to make a call to /.ory/.../whoami through the proxy. However i think axios wants to make this call at localhost port 80, leading to the following error

[0] Error: connect ECONNREFUSED ::1:80
[0]     at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1161:16) {
[0]   errno: -61,
[0]   code: 'ECONNREFUSED',
[0]   syscall: 'connect',
[0]   address: '::1',
[0]   port: 80,
[0]   config: {
[0]     url: '/.ory/sessions/whoami',
[0]     method: 'get',
[0]     headers: {
[0]       Accept: 'application/json, text/plain, */*',
[0]       Cookie: '__cflb=0pg1QYeUHkKyPHC72r3PJ1fj2WK6WMwzqHhgHXum; csrf_token_a5d02dd42b4ef065bbbd5ed674b19b5d2e6dc4f2a3e4acc8684f15ae24c19b97=JGnPuz6b+Jqy10PCRqwvR2dgrw2UXJ1K96SHlDCWSag=; ory_session_greatgoldwasserlbe7q6kfiv=MTY1MDMwMTk3MnxnSmhfWkRBM2lSVkJwX1JpY0oyYUpGV21lbm9jel9PWkl0a2RwVzJ0eGRJT1lLSm9JMlZUUjZyc0xYalJyMS1naC0zS2FleWxaM0lsT0pxMjNSRkRGQVlTbjU2ZUtaYTAxVEQ4MWxoZUlfcFR6Rml3YkM4bE1XdmVQQms3SjhZR0NaQ2UwMklqcXc9PXygWBBkEKzVhZUiBc1uzDEO0KmKCRdEUET-qIkFgs5LkQ==',

So we need to tell axios it should match the port we used when we started the proxy

"dev:proxy": "ory proxy --no-jwt --port 8000 http://localhost:8001/"

some solutions at the doc level

  1. insist we pass a proxy to axios in development environments
.toSession(undefined, req.header('cookie'), {
    proxy: {
        host: 'localhost',
        port: 8000
    }
})
  1. in development make sure we pass the full base path inclusive of port
const ory = new orySDK.V0alpha2Api(
    new orySDK.Configuration(
        // @ts-ignore
        {basePath: 'http://localhost:8000/.ory',
            baseOptions: {
                withCredentials: true
            }
        }
    )
)

These both work and i am also wondering

  1. if there is a way to detect if we are proxying and on what port so this could be done automatically somehow
  2. perhaps having this as an envar like the sdk url

https://github.com/ory/docs/blob/master/code-examples/protect-page-login/expressjs/routes/index.js

Reproducing the bug

  1. follow example on https://www.ory.sh/docs/guides/protect-page-login/expressjs
  2. register a user
  3. observe redirect loop once user registered due to failing whoami request

Relevant log output

No response

Relevant configuration

No response

Version

"@ory/client": "^0.0.1-alpha.167"

On which operating system are you observing this issue?

macOS

In which environment are you deploying?

Ory Cloud

Additional Context

No response

ammanvedi avatar Apr 18 '22 17:04 ammanvedi

also happy to contribute the fix!!

ammanvedi avatar Apr 18 '22 22:04 ammanvedi

that would be lovely, @Benehiko can you please assist?

aeneasr avatar Apr 19 '22 00:04 aeneasr

Strange, we have e2e tests for this which are green on master, so not sure how this is failing here. Maybe there is a missing configuration somewhere. https://github.com/ory/docs/blob/master/tests/playwright/protect-page-login.spec.ts

Benehiko avatar Apr 20 '22 06:04 Benehiko

Are the e2e tests using the exact same instructions as the OP suggested?

aeneasr avatar Apr 20 '22 14:04 aeneasr

I believe so, since we check that the session exists afterwards containing the registered email here.

I don't see how we would have a redirect loop then if we return to the application "dashboard" showing the session information.

Benehiko avatar Apr 20 '22 14:04 Benehiko

So do the docs or e2e tests need to be adjusted to follow the same commands?

aeneasr avatar Apr 20 '22 14:04 aeneasr

We should just update the documentation, it seems we don't give enough in the step by step process to build the example correctly. We should also indicate that the sdk will call whichever url the browser is currently requesting from, e.g. browser is on http://localhost:4000 and thus the sdk will match that. So if this is setup incorrectly, e.g. the node application is running on localhost:80 and the browser is requesting the node application directly, we will end up in an error state.

Benehiko avatar Apr 21 '22 06:04 Benehiko

@ammanvedi could you please copy the code given on GitHub directly? You can find the project here https://github.com/ory/docs/tree/master/code-examples/protect-page-login/expressjs

Try reproduce the error and take note of the differences in code that you currently have vs the GitHub clone. I think the steps given in the guide isn't specific enough.

Benehiko avatar Apr 21 '22 06:04 Benehiko

@Benehiko sure i will try !

ammanvedi avatar Apr 21 '22 15:04 ammanvedi

Sorry for the delay i will try this tonight

ammanvedi avatar Apr 26 '22 09:04 ammanvedi

Okay i have tried this and here are my steps

git clone https://github.com/ory/docs.git
cd docs/code-examples/protect-page-login/expressjs
npm install

i then edit the proxy npm script so it contains the sdk url envar which is the same as it would be in the tests

    "proxy": "ORY_SDK_URL=https://playground.projects.oryapis.com ory proxy --no-jwt --port 4000 http://localhost:3000/"

then

npm run proxy
npm run start

then in my browser i visit http://localhost:4000/

and this works fine. i can sign up etc.

However if i use my own sdk url

    "proxy": "ORY_SDK_URL=https://ABCDEF.projects.oryapis.com ory proxy --no-jwt --port 4000 http://localhost:3000/"

then it breaks;

https://user-images.githubusercontent.com/1761300/165363228-39436e9a-0900-49da-96ff-90058bae363c.mov

WHY?

i think it has something to do with

// code-examples/protect-page-login/expressjs/routes/index.js
baseUrl: '/.ory'

this baseUrl property is not specified by the sdk config, the config actually accepts basePath. When basePath is not found the default becomes

// code-examples/protect-page-login/expressjs/node_modules/@ory/client/base.ts

export const BASE_PATH = "https://playground.projects.oryapis.com".replace(/\/+$/, "");
this.basePath = configuration.basePath || this.basePath;

i think this could be why the tests work because the base path that gets set is not a local path, its an absolute url, because it gets defaulted to that, and the SDK_URL in tests is playground also

SOLUTION

the solution could be to make the following change

var ory = new sdk.V0alpha2Api(
  new sdk.Configuration({
    basePath: 'http://localhost:4000/.ory'
  })
)
  1. baseUrl -> basePath
  2. /.ory -> 'http://localhost:4000/.ory'

would probably need to match the ports in express app to the test setup so this url work in both places

cd code-examples/protect-page-login/expressjs && \
  PORT=4002 npm run start &
ory proxy --no-jwt --port 3002 http://localhost:4002/ &

was a bit of rabbit hole but would appreciate a sanity check on this

ammanvedi avatar Apr 26 '22 19:04 ammanvedi

Hi @ammanvedi

Thank you for the detailed write-up. I will take a look today at it using the steps you provided

Benehiko avatar Apr 27 '22 06:04 Benehiko

It seems like the SDK is not getting the current origin the browser is on e.g. localhost:4000 and so it defaults to localhost:80 which obviously doesn't have anything hosted on it and thus the express middleware ends up in a redirect loop trying to go back to the login screen.

Here is an example of the error that is caught just before redirecting to /.ory/ui/login.

Error: connect ECONNREFUSED 127.0.0.1:80
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1187:16) {
  errno: -111,
  code: 'ECONNREFUSED',
  syscall: 'connect',
  address: '127.0.0.1',
  port: 80,
  config: {
    url: '/.ory/sessions/whoami',

We need to update the example to something like the go example

https://github.com/ory/docs/blob/master/code-examples/protect-page-login/go/main.go#L16-L24

Benehiko avatar Jun 21 '22 16:06 Benehiko

Nice find, thank you @Benehiko ! Could you make those changes to the example? :)

aeneasr avatar Jun 22 '22 08:06 aeneasr

Yeah I'll work on that soon, could you assign me to the issue?

Benehiko avatar Jun 22 '22 14:06 Benehiko