netlify / cli

Netlify Command Line Interface
http://cli.netlify.com
MIT License
1.58k stars 358 forks source link

[feature] local emulation of Netlify Identity #440

Open swyxio opened 5 years ago

swyxio commented 5 years ago

- Do you want to request a feature or report a bug? feature

- What is the current behavior? we currently can only do very limited decoding of JWTs but that isnt even a fraction of what we need to do for netlify identity dev.

with the ideal contract, we can offer local emulation of Netlify Identity (having some session state, and just focusing on letting people test signup flows (as well as maybe firing off identity event triggers!))

things to replicate:

richtr commented 4 years ago

Related issues running local custom Netlify Identity:

https://github.com/netlify/cli/issues/529 https://github.com/netlify/cli/issues/621

zachwolf commented 3 years ago

Is there any change with this area? I'm using netlify for the first time and feel like maybe I'm missing something obvious. I can't figure out how to develop apps locally using netlify's provided authentication.

erezrokah commented 3 years ago

Hi @zachwolf are you experiencing a specific error? Are you using the identity widget?

allpwrfulroot commented 3 years ago

I am using the widget, have not yet figured out how to get identity to work locally with either netlify dev or any of the several suggestions you can find via googling? Need to debug a triggered function and so far not seeing any way to do that.

erezrokah commented 3 years ago

Hi @allpwrfulroot this might help for debugging functions. If you add an authorization header to functions requests the CLI injects an emulated identity context

If those suggestions are not helpful, can you describe using a step by step guide (possibly with an example repo) your use case. Please state the actual result and expected result.

crock commented 3 years ago

So I opened a support ticket for my issue, but they told me to open an issue here since it's related. I believe netlify dev command is stripping the Authorization header from a request to one of the admin endpoints in a Netlify Function. Here's a screenshot of the console output and the relevant code.

Some more context for the screenshot: The variables that are defined off-screen are url, token, and sellerId which are mapped to as followed:

const { identity, user { sub: sellerId } } = context.clientContext
const { url, token }  = identity

Screenshot

Pieparker commented 3 years ago

Hey team! Adding a comment on behalf of a customer in the Helpdesk (see https://netlify.zendesk.com/agent/tickets/61073).

Works in prod:

This does not work locally:

NOTE: netlify dev --live also fails this test

Wondered if you could share your 2c about this!

erezrokah commented 3 years ago

Hi @Pieparker, this is a tricky one and there are several issues preventing from this scenario to work. In order for Role based redirects to work the browser needs to send the nt_jwt cookie with the request (the cookie value is basically the user access token). This doesn't work locally because:

  1. The Netlify Identity widget needs to pass the x-use-cookie header to Netlify Identity which doesn't happen at the moment when running on localhost. The means the set-cookie header is missing from the response.
  2. Forcing the GoTrue client to send the cookie doesn't work (one could do it via netlifyIdentity.gotrue.setCookie = true) since the browser won't set the cookie since the authentication request domain is different from localhost. We might be able to fix that by modifying the credentials options here and here.
  3. Even if we can get the cookie to be set correctly redirects matching won't work as the CLI uses a default JWT secret and roles path to verify the JWT token. The CLI doesn't know the Netlify Identity secret, and the path to get the Identity roles is app_metadata.roles and not the default app_metadata.authorization.roles.

However, not all is lost, I was able to find a simple workaround using the following code:

<head>
  <script
    type="text/javascript"
    src="https://identity.netlify.com/v1/netlify-identity-widget.js"
  ></script>
  <script>
    if (
      location.hostname === "localhost" ||
      location.hostname === "127.0.0.1"
    ) {
      /* Signed using "secret" and decodes to
        {
          "exp": 1893456000,
          "sub": "12345678",
          "email": "admin@admin.com",
          "app_metadata": {
            "authorization": {
              "roles": [
                "admin"
              ]
            }
          },
          "user_metadata": {}
        }
      */
      const fakeJWT =
        "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4OTM0NTYwMDAsInN1YiI6IjEyMzQ1Njc4IiwiZW1haWwiOiJhZG1pbkBhZG1pbi5jb20iLCJhcHBfbWV0YWRhdGEiOnsiYXV0aG9yaXphdGlvbiI6eyJyb2xlcyI6WyJhZG1pbiJdfX0sInVzZXJfbWV0YWRhdGEiOnt9fQ.hOSRyH73Ps4poJ4RrB22lLSOHrk25xiwyVPCVyS6XpQ";
      netlifyIdentity.on("login", (user) => {
        document.cookie = `nf_jwt=${fakeJWT};`;
      });
      netlifyIdentity.on("logout", () => {
        document.cookie = `nf_jwt= ; expires = Thu, 01 Jan 1970 00:00:00 GMT`;
      });
    }
  </script>
</head>
<body>
  This is an index page
  <div data-netlify-identity-button>Login</div>
</body>

Going forward I believe ntl dev should be identity aware so it can proxy and modify the requests to the identity service.

designbuedchen commented 2 years ago

Is there already someone aware of what @crock wrote regarding the missing "Authorization" header on requests to the emulated Identity endpoint https://netlify-dev-locally-emulated-identity.netlify.app/.netlify/identity/ ?

Even when directly hitting this endpoint with Postman and using the credentials which the netlify dev command serves, the "Authorization" header is totally omitted. It seems, that maybe in a preflight check the server responds with the cors info, that this custom header is not allowed to be used for the endpoint?