Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client & server side method for validating user auth token #147

Closed
thorwebdev opened this issue Aug 19, 2020 · 8 comments · Fixed by supabase/supabase-js#50
Closed

Client & server side method for validating user auth token #147

thorwebdev opened this issue Aug 19, 2020 · 8 comments · Fixed by supabase/supabase-js#50

Comments

@thorwebdev
Copy link
Member

I'm submitting a ...

  • feature request

Summary
It would be great to be able to validate that a user is currently authenticated and for example has a specific role (admin) etc.

Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.)

This is how Firebase handles this:

Here an example how that is being used with Next.js: https://github.com/vercel/next.js/blob/canary/examples/with-firebase-authentication/pages/api/getFood.js#L8

@kiwicopple
Copy link
Member

Let me know if I have this one correct - based on the next.js example the scenario would be:

  1. grab the current cookie (either from the browser or the req)
  2. send to GoTrue
  3. GoTrue needs to validate that the JWT is still valid
  4. If it is valid, give back the user data (including UID)

@awalias it looks like this could already be solved by supabase.auth.user() right?
https://github.com/supabase/supabase-js/blob/108579d064179043dbee0199aa2ddb4e4cb8e567/src/Auth.js#L104

Assuming that is true:

  • We would need to do something to pull the cookie out of the req (?).
  • We may need to add a forceRefresh param to bypass the this.currentUser check (consistent with Firebase)

@thorwebdev
Copy link
Member Author

@kiwicopple the workflow I'd want to do is:

  1. client: get current authenticated user token
  2. client: send request to backend with user token
  3. server: validate the user token and get their uid (now I know that they are correctly authenticated)
  4. server: update their customer details in Stripe or other action we only want to perform for authenticated users.

@phamhieu
Copy link
Member

Supabase-js does exactly like your workflow @thorsten-stripe with this method supabase.auth.user()

We should expose auth api on the docs https://supabase.io/docs/library/user-management. Right now, User Management docs seems magical and limited with only supabase-js how-to.

@thorwebdev
Copy link
Member Author

Thanks @phamhieu, yes, we'll need to document the server-side side of things. And potentially should think about "admin" auth methods that can be used in a server context, because supabase.auth.user() relies on the client-side cookies/localStorage, right?

@phamhieu
Copy link
Member

phamhieu commented Aug 28, 2020

because supabase.auth.user() relies on the client-side cookies/localStorage, right?
--> yes, you're right

While waiting for Supabase document to be updated, you can try https://github.com/netlify/gotrue. The only difference is you need to include 'apiKey' (your-project-anon-key) in your request header.
Supabase gotrue api endpoint is at {SUPABASE_URL}/auth/v1.

Screenshot 2020-08-28 at 4 18 25 PM

@thorwebdev
Copy link
Member Author

Quick papertrail update from yesterday:

This issue relates to: supabase/supabase-js#20

We've made the decision to allow passing of the JWT to the user method which will allow validating and retrieving a user server-side based on a JWT sent from the client:

const response = await supabase.auth.user({ jwt: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxx" })

success response:

{
  "error": null,
  "user": {
    "id": "25a3ef18-fe11-483a-ab89-60936b95a3eb",
    "aud": "authenticated",
    "role": "authenticated",
    "email": "testr@test.de",
    "confirmed_at": "2020-09-05T08:54:29.881642986Z",
    "last_sign_in_at": "2020-09-05T08:54:29.887012586Z",
    "app_metadata": {
      "provider": "email"
    },
    "user_metadata": null,
    "created_at": "2020-09-05T08:54:29.877021Z",
    "updated_at": "2020-09-05T08:54:29.88178Z"
  }
}

error response:

{
  "error": {
    "code": 400,
    "message": "Could not read User ID claim"
  },
  "user": null
}

@kiwicopple can you link the forked "gotrue-js" spec once ready?

This also relates to the general supabase-js DX change: supabase/supabase-js#32

kiwicopple added a commit to supabase/supabase-js that referenced this issue Nov 2, 2020

- Fixes #32 Major DX change: response and error handling
- Fixes #49 When no `supabaseKey` is passed in it throws an error
- Fixes #31 chore: set up semantic releases
- Fixes #15 `supabase.auth.logout()` throws "Invalid user" error.
- Fixes #20 Auth: Change DX of user management
- Fixes #30 Supabase auth interface missing informiation
- Fixes supabase/supabase#147 supabase/supabase#147
- Partial fix for supabase/realtime-js#53  - if there is no token provided. The error needs to be caught at a socket level.
- Adds magic links


## BREAKING CHANGES

- See all breaking changes in RELEASE.md v1.0.0
- Errors are now returned and not thrown
- Auth now uses `@supabase/gotrue-js` interface
- `supabase.getSubscriptions()` only returns open subscriptions



* Updates the config

* chore: Migrates the basic outline to TS

* Adds a simple example showing how it can be used.

* chore: Moves tests to jest

* chore: Adds semantic releases

* Moves the subscription into it's own class

* Updates the todo readme with simple instructions

* Updates installs

* Revverts commented code - sorry for the spam

* docs: adds JSDoc to some functions

* chore: Adds a function for backwards compat

* chore: migrates the client to SupabaseClient

* This change attempts to make the naming conventions the same as Thor's previously

* Updates GoTrue to latest version

* Adds generic type to the from, and updates the name of the query builder

* Updates to latest versions of all packages

* Updates the example to make sure it's working

* Refactor SupabaseQueryBuilder

* Adds prettier hook

* Add TypeScript next.js example.

* Declutter SupabaseClient and make work with gotrue-js changes.

* Bumps the GoTrue version

* Bumps postgrest to include the types

* Temporarily adds the spec so that I can use it in our docs

* Update examples and add resetPassword.

* Bump gotrue-js version.

* Update lockfile.

* Add auth magic link capabilities.

* Gotrue-js user and session method updates.

* chore: Adds release notes

Co-authored-by: Thorsten Schaeff <thorsten.schaeff@gmail.com>
Co-authored-by: Thor 雷神 Schaeff <5748289+thorwebdev@users.noreply.github.com>
@shellscape
Copy link

@thorwebdev @kiwicopple what happened to the function signature shown here? #147 (comment) #50 doesn't appear to add that signature and I can't find a blame trail for when that was added. We're in need of validating a JWT serverside and I'm not coming up with any other options.

@thorwebdev
Copy link
Member Author

thorwebdev commented Oct 22, 2021

@shellscape this has since been moved to the admin/api namespace: https://github.com/supabase/gotrue-js/blob/master/src/GoTrueApi.ts#L322

const { data: user, error } = await supabase.auth.api.getUser(token)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants