GithubHelp home page GithubHelp logo

supabase / auth Goto Github PK

View Code? Open in Web Editor NEW
1.3K 19.0 319.0 20.36 MB

A JWT based API for managing users and issuing JWT tokens

Home Page: https://supabase.com/docs/guides/auth

License: MIT License

Go 98.98% Makefile 0.26% Shell 0.12% Dockerfile 0.07% PLpgSQL 0.57%
authentication auth authorization jwt go supabase client-auth

auth's Introduction

Auth - Authentication and User Management by Supabase

Coverage Status

Auth is a user management and authentication server written in Go that powers Supabase's features such as:

  • Issuing JWTs
  • Row Level Security with PostgREST
  • User management
  • Sign in with email, password, magic link, phone number
  • Sign in with external providers (Google, Apple, Facebook, Discord, ...)

It is originally based on the excellent GoTrue codebase by Netlify, however both have diverged significantly in features and capabilities.

If you wish to contribute to the project, please refer to the contributing guide.

Table Of Contents

Quick Start

Create a .env file to store your own custom env vars. See example.env

  1. Start the local postgres database in a postgres container: docker-compose -f docker-compose-dev.yml up postgres
  2. Build the auth binary: make build . You should see an output like this:
go build -ldflags "-X github.com/supabase/auth/cmd.Version=`git rev-parse HEAD`"
GOOS=linux GOARCH=arm64 go build -ldflags "-X github.com/supabase/auth/cmd.Version=`git rev-parse HEAD`" -o gotrue-arm64
  1. Execute the auth binary: ./gotrue

If you have docker installed

Create a .env.docker file to store your own custom env vars. See example.docker.env

  1. make build
  2. make dev
  3. docker ps should show 2 docker containers (auth_postgresql and gotrue_gotrue)
  4. That's it! Visit the health checkendpoint to confirm that auth is running.

Running in production

Running an authentication server in production is not an easy feat. We recommend using Supabase Auth which gets regular security updates.

Otherwise, please make sure you setup a process to promptly update to the latest version. You can do that by following this repository, specifically the Releases and Security Advisories sections.

Backward compatibility

Auth uses the Semantic Versioning scheme. Here are some further clarifications on backward compatibility guarantees:

Go API compatibility

Auth is not meant to be used as a Go library. There are no guarantees on backward API compatibility when used this way regardless which version number changes.

Patch

Changes to the patch version guarantees backward compatibility with:

  • Database objects (tables, columns, indexes, functions).
  • REST API
  • JWT structure
  • Configuration

Guaranteed examples:

  • A column won't change its type.
  • A table won't change its primary key.
  • An index will not be removed.
  • A uniqueness constraint will not be removed.
  • A REST API will not be removed.
  • Parameters to REST APIs will work equivalently as before (or better, if a bug has been fixed).
  • Configuration will not change.

Not guaranteed examples:

  • A table may add new columns.
  • Columns in a table may be reordered.
  • Non-unique constraints may be removed (database level checks, null, default values).
  • JWT may add new properties.

Minor

Changes to minor version guarantees backward compatibility with:

  • REST API
  • JWT structure
  • Configuration

Exceptions to these guarantees will be made only when serious security issues are found that can't be remedied in any other way.

Guaranteed examples:

  • Existing APIs may be deprecated but continue working for the next few minor version releases.
  • Configuration changes may become deprecated but continue working for the next few minor version releases.
  • Already issued JWTs will be accepted, but new JWTs may be with a different structure (but usually similar).

Not guaranteed examples:

  • Removal of JWT fields after a deprecation notice.
  • Removal of certain APIs after a deprecation notice.
  • Removal of sign-in with external providers, after a deprecation notice.
  • Deletion, truncation, significant schema changes to tables, indexes, views, functions.

We aim to provide a deprecation notice in execution logs for at least two major version releases or two weeks if multiple releases go out. Compatibility will be guaranteed while the notice is live.

Major

Changes to the major version do not guarantee any backward compatibility with previous versions.

Inherited features

Certain inherited features from the Netlify codebase are not supported by Supabase and they may be removed without prior notice in the future. This is a comprehensive list of those features:

  1. Multi-tenancy via the instances table i.e. GOTRUE_MULTI_INSTANCE_MODE configuration parameter.
  2. System user (zero UUID user).
  3. Super admin via the is_super_admin column.
  4. Group information in JWTs via GOTRUE_JWT_ADMIN_GROUP_NAME and other configuration fields.
  5. Symmetrics JWTs. In the future it is very likely that Auth will begin issuing asymmetric JWTs (subject to configuration), so do not rely on the assumption that only HS256 signed JWTs will be issued long term.

Note that this is not an exhaustive list and it may change.

Best practices when self-hosting

These are some best practices to follow when self-hosting to ensure backward compatibility with Auth:

  1. Do not modify the schema managed by Auth. You can see all of the migrations in the migrations directory.
  2. Do not rely on schema and structure of data in the database. Always use Auth APIs and JWTs to infer information about users.
  3. Always run Auth behind a TLS-capable proxy such as a load balancer, CDN, nginx or other similar software.

Configuration

You may configure Auth using either a configuration file named .env, environment variables, or a combination of both. Environment variables are prefixed with GOTRUE_, and will always have precedence over values provided via file.

Top-Level

GOTRUE_SITE_URL=https://example.netlify.com/

SITE_URL - string required

The base URL your site is located at. Currently used in combination with other settings to construct URLs used in emails. Any URI that shares a host with SITE_URL is a permitted value for redirect_to params (see /authorize etc.).

URI_ALLOW_LIST - string

A comma separated list of URIs (e.g. "https://foo.example.com,https://*.foo.example.com,https://bar.example.com") which are permitted as valid redirect_to destinations. Defaults to []. Supports wildcard matching through globbing. e.g. https://*.foo.example.com will allow https://a.foo.example.com and https://b.foo.example.com to be accepted. Globbing is also supported on subdomains. e.g. https://foo.example.com/* will allow https://foo.example.com/page1 and https://foo.example.com/page2 to be accepted.

For more common glob patterns, check out the following link.

OPERATOR_TOKEN - string Multi-instance mode only

The shared secret with an operator (usually Netlify) for this microservice. Used to verify requests have been proxied through the operator and the payload values can be trusted.

DISABLE_SIGNUP - bool

When signup is disabled the only way to create new users is through invites. Defaults to false, all signups enabled.

GOTRUE_EXTERNAL_EMAIL_ENABLED - bool

Use this to disable email signups (users can still use external oauth providers to sign up / sign in)

GOTRUE_EXTERNAL_PHONE_ENABLED - bool

Use this to disable phone signups (users can still use external oauth providers to sign up / sign in)

GOTRUE_RATE_LIMIT_HEADER - string

Header on which to rate limit the /token endpoint.

GOTRUE_RATE_LIMIT_EMAIL_SENT - string

Rate limit the number of emails sent per hr on the following endpoints: /signup, /invite, /magiclink, /recover, /otp, & /user.

GOTRUE_PASSWORD_MIN_LENGTH - int

Minimum password length, defaults to 6.

GOTRUE_PASSWORD_REQUIRED_CHARACTERS - a string of character sets separated by :. A password must contain at least one character of each set to be accepted. To use the : character escape it with \.

GOTRUE_SECURITY_REFRESH_TOKEN_ROTATION_ENABLED - bool

If refresh token rotation is enabled, auth will automatically detect malicious attempts to reuse a revoked refresh token. When a malicious attempt is detected, gotrue immediately revokes all tokens that descended from the offending token.

GOTRUE_SECURITY_REFRESH_TOKEN_REUSE_INTERVAL - string

This setting is only applicable if GOTRUE_SECURITY_REFRESH_TOKEN_ROTATION_ENABLED is enabled. The reuse interval for a refresh token allows for exchanging the refresh token multiple times during the interval to support concurrency or offline issues. During the reuse interval, auth will not consider using a revoked token as a malicious attempt and will simply return the child refresh token.

Only the previous revoked token can be reused. Using an old refresh token way before the current valid refresh token will trigger the reuse detection.

API

GOTRUE_API_HOST=localhost
PORT=9999
API_EXTERNAL_URL=http://localhost:9999

API_HOST - string

Hostname to listen on.

PORT (no prefix) / API_PORT - number

Port number to listen on. Defaults to 8081.

API_ENDPOINT - string Multi-instance mode only

Controls what endpoint Netlify can access this API on.

API_EXTERNAL_URL - string required

The URL on which Gotrue might be accessed at.

REQUEST_ID_HEADER - string

If you wish to inherit a request ID from the incoming request, specify the name in this value.

Database

GOTRUE_DB_DRIVER=postgres
DATABASE_URL=root@localhost/auth

DB_DRIVER - string required

Chooses what dialect of database you want. Must be postgres.

DATABASE_URL (no prefix) / DB_DATABASE_URL - string required

Connection string for the database.

GOTRUE_DB_MAX_POOL_SIZE - int

Sets the maximum number of open connections to the database. Defaults to 0 which is equivalent to an "unlimited" number of connections.

DB_NAMESPACE - string

Adds a prefix to all table names.

Migrations Note

Migrations are applied automatically when you run ./auth. However, you also have the option to rerun the migrations via the following methods:

  • If built locally: ./auth migrate
  • Using Docker: docker run --rm auth gotrue migrate

Logging

LOG_LEVEL=debug # available without GOTRUE prefix (exception)
GOTRUE_LOG_FILE=/var/log/go/auth.log

LOG_LEVEL - string

Controls what log levels are output. Choose from panic, fatal, error, warn, info, or debug. Defaults to info.

LOG_FILE - string

If you wish logs to be written to a file, set log_file to a valid file path.

Observability

Auth has basic observability built in. It is able to export OpenTelemetry metrics and traces to a collector.

Tracing

To enable tracing configure these variables:

GOTRUE_TRACING_ENABLED - boolean

GOTRUE_TRACING_EXPORTER - string only opentelemetry supported

Make sure you also configure the OpenTelemetry Exporter configuration for your collector or service.

For example, if you use Honeycomb.io you should set these standard OpenTelemetry OTLP variables:

OTEL_SERVICE_NAME=auth
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.honeycomb.io:443
OTEL_EXPORTER_OTLP_HEADERS="x-honeycomb-team=<API-KEY>,x-honeycomb-dataset=auth"

Metrics

To enable metrics configure these variables:

GOTRUE_METRICS_ENABLED - boolean

GOTRUE_METRICS_EXPORTER - string only opentelemetry and prometheus supported

Make sure you also configure the OpenTelemetry Exporter configuration for your collector or service.

If you use the prometheus exporter, the server host and port can be configured using these standard OpenTelemetry variables:

OTEL_EXPORTER_PROMETHEUS_HOST - IP address, default 0.0.0.0

OTEL_EXPORTER_PROMETHEUS_PORT - port number, default 9100

The metrics are exported on the / path on the server.

If you use the opentelemetry exporter, the metrics are pushed to the collector.

For example, if you use Honeycomb.io you should set these standard OpenTelemetry OTLP variables:

OTEL_SERVICE_NAME=auth
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.honeycomb.io:443
OTEL_EXPORTER_OTLP_HEADERS="x-honeycomb-team=<API-KEY>,x-honeycomb-dataset=auth"

Note that Honeycomb.io requires a paid plan to ingest metrics.

If you need to debug an issue with traces or metrics not being pushed, you can set DEBUG=true to get more insights from the OpenTelemetry SDK.

Custom resource attributes

When using the OpenTelemetry tracing or metrics exporter you can define custom resource attributes using the standard OTEL_RESOURCE_ATTRIBUTES environment variable.

A default attribute auth.version is provided containing the build version.

Tracing HTTP routes

All HTTP calls to the Auth API are traced. Routes use the parametrized version of the route, and the values for the route parameters can be found as the http.route.params.<route-key> span attribute.

For example, the following request:

GET /admin/users/4acde936-82dc-4552-b851-831fb8ce0927/

will be traced as:

http.method = GET
http.route = /admin/users/{user_id}
http.route.params.user_id = 4acde936-82dc-4552-b851-831fb8ce0927

Go runtime and HTTP metrics

All of the Go runtime metrics are exposed. Some HTTP metrics are also collected by default.

JSON Web Tokens (JWT)

GOTRUE_JWT_SECRET=supersecretvalue
GOTRUE_JWT_EXP=3600
GOTRUE_JWT_AUD=netlify

JWT_SECRET - string required

The secret used to sign JWT tokens with.

JWT_EXP - number

How long tokens are valid for, in seconds. Defaults to 3600 (1 hour).

JWT_AUD - string

The default JWT audience. Use audiences to group users.

JWT_ADMIN_GROUP_NAME - string

The name of the admin group (if enabled). Defaults to admin.

JWT_DEFAULT_GROUP_NAME - string

The default group to assign all new users to.

External Authentication Providers

We support apple, azure, bitbucket, discord, facebook, figma, github, gitlab, google, keycloak, linkedin, notion, spotify, slack, twitch, twitter and workos for external authentication.

Use the names as the keys underneath external to configure each separately.

GOTRUE_EXTERNAL_GITHUB_ENABLED=true
GOTRUE_EXTERNAL_GITHUB_CLIENT_ID=myappclientid
GOTRUE_EXTERNAL_GITHUB_SECRET=clientsecretvaluessssh
GOTRUE_EXTERNAL_GITHUB_REDIRECT_URI=http://localhost:3000/callback

No external providers are required, but you must provide the required values if you choose to enable any.

EXTERNAL_X_ENABLED - bool

Whether this external provider is enabled or not

EXTERNAL_X_CLIENT_ID - string required

The OAuth2 Client ID registered with the external provider.

EXTERNAL_X_SECRET - string required

The OAuth2 Client Secret provided by the external provider when you registered.

EXTERNAL_X_REDIRECT_URI - string required

The URI a OAuth2 provider will redirect to with the code and state values.

EXTERNAL_X_URL - string

The base URL used for constructing the URLs to request authorization and access tokens. Used by gitlab and keycloak. For gitlab it defaults to https://gitlab.com. For keycloak you need to set this to your instance, for example: https://keycloak.example.com/realms/myrealm

Apple OAuth

To try out external authentication with Apple locally, you will need to do the following:

  1. Remap localhost to <my_custom_dns > in your /etc/hosts config.

  2. Configure auth to serve HTTPS traffic over localhost by replacing ListenAndServe in api.go with:

       func (a *API) ListenAndServe(hostAndPort string) {
         log := logrus.WithField("component", "api")
         path, err := os.Getwd()
         if err != nil {
           log.Println(err)
         }
         server := &http.Server{
           Addr:    hostAndPort,
           Handler: a.handler,
         }
         done := make(chan struct{})
         defer close(done)
         go func() {
           waitForTermination(log, done)
           ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
           defer cancel()
           server.Shutdown(ctx)
         }()
         if err := server.ListenAndServeTLS("PATH_TO_CRT_FILE", "PATH_TO_KEY_FILE"); err != http.ErrServerClosed {
           log.WithError(err).Fatal("http server listen failed")
         }
     }
    
  3. Generate the crt and key file. See here for more information.

  4. Generate the GOTRUE_EXTERNAL_APPLE_SECRET by following this post!

E-Mail

Sending email is not required, but highly recommended for password recovery. If enabled, you must provide the required values below.

GOTRUE_SMTP_HOST=smtp.mandrillapp.com
GOTRUE_SMTP_PORT=587
GOTRUE_SMTP_USER[email protected]
GOTRUE_SMTP_PASS=correcthorsebatterystaple
GOTRUE_SMTP_ADMIN_EMAIL[email protected]
GOTRUE_MAILER_SUBJECTS_CONFIRMATION="Please confirm"

SMTP_ADMIN_EMAIL - string required

The From email address for all emails sent.

SMTP_HOST - string required

The mail server hostname to send emails through.

SMTP_PORT - number required

The port number to connect to the mail server on.

SMTP_USER - string

If the mail server requires authentication, the username to use.

SMTP_PASS - string

If the mail server requires authentication, the password to use.

SMTP_MAX_FREQUENCY - number

Controls the minimum amount of time that must pass before sending another signup confirmation or password reset email. The value is the number of seconds. Defaults to 900 (15 minutes).

SMTP_SENDER_NAME - string

Sets the name of the sender. Defaults to the SMTP_ADMIN_EMAIL if not used.

MAILER_AUTOCONFIRM - bool

If you do not require email confirmation, you may set this to true. Defaults to false.

MAILER_OTP_EXP - number

Controls the duration an email link or otp is valid for.

MAILER_URLPATHS_INVITE - string

URL path to use in the user invite email. Defaults to /verify.

MAILER_URLPATHS_CONFIRMATION - string

URL path to use in the signup confirmation email. Defaults to /verify.

MAILER_URLPATHS_RECOVERY - string

URL path to use in the password reset email. Defaults to /verify.

MAILER_URLPATHS_EMAIL_CHANGE - string

URL path to use in the email change confirmation email. Defaults to /verify.

MAILER_SUBJECTS_INVITE - string

Email subject to use for user invite. Defaults to You have been invited.

MAILER_SUBJECTS_CONFIRMATION - string

Email subject to use for signup confirmation. Defaults to Confirm Your Signup.

MAILER_SUBJECTS_RECOVERY - string

Email subject to use for password reset. Defaults to Reset Your Password.

MAILER_SUBJECTS_MAGIC_LINK - string

Email subject to use for magic link email. Defaults to Your Magic Link.

MAILER_SUBJECTS_EMAIL_CHANGE - string

Email subject to use for email change confirmation. Defaults to Confirm Email Change.

MAILER_TEMPLATES_INVITE - string

URL path to an email template to use when inviting a user. (e.g. https://www.example.com/path-to-email-template.html) SiteURL, Email, and ConfirmationURL variables are available.

Default Content (if template is unavailable):

<h2>You have been invited</h2>

<p>
  You have been invited to create a user on {{ .SiteURL }}. Follow this link to
  accept the invite:
</p>
<p><a href="{{ .ConfirmationURL }}">Accept the invite</a></p>

MAILER_TEMPLATES_CONFIRMATION - string

URL path to an email template to use when confirming a signup. (e.g. https://www.example.com/path-to-email-template.html) SiteURL, Email, and ConfirmationURL variables are available.

Default Content (if template is unavailable):

<h2>Confirm your signup</h2>

<p>Follow this link to confirm your user:</p>
<p><a href="{{ .ConfirmationURL }}">Confirm your mail</a></p>

MAILER_TEMPLATES_RECOVERY - string

URL path to an email template to use when resetting a password. (e.g. https://www.example.com/path-to-email-template.html) SiteURL, Email, and ConfirmationURL variables are available.

Default Content (if template is unavailable):

<h2>Reset Password</h2>

<p>Follow this link to reset the password for your user:</p>
<p><a href="{{ .ConfirmationURL }}">Reset Password</a></p>

MAILER_TEMPLATES_MAGIC_LINK - string

URL path to an email template to use when sending magic link. (e.g. https://www.example.com/path-to-email-template.html) SiteURL, Email, and ConfirmationURL variables are available.

Default Content (if template is unavailable):

<h2>Magic Link</h2>

<p>Follow this link to login:</p>
<p><a href="{{ .ConfirmationURL }}">Log In</a></p>

MAILER_TEMPLATES_EMAIL_CHANGE - string

URL path to an email template to use when confirming the change of an email address. (e.g. https://www.example.com/path-to-email-template.html) SiteURL, Email, NewEmail, and ConfirmationURL variables are available.

Default Content (if template is unavailable):

<h2>Confirm Change of Email</h2>

<p>
  Follow this link to confirm the update of your email from {{ .Email }} to {{
  .NewEmail }}:
</p>
<p><a href="{{ .ConfirmationURL }}">Change Email</a></p>

Phone Auth

SMS_AUTOCONFIRM - bool

If you do not require phone confirmation, you may set this to true. Defaults to false.

SMS_MAX_FREQUENCY - number

Controls the minimum amount of time that must pass before sending another sms otp. The value is the number of seconds. Defaults to 60 (1 minute)).

SMS_OTP_EXP - number

Controls the duration an sms otp is valid for.

SMS_OTP_LENGTH - number

Controls the number of digits of the sms otp sent.

SMS_PROVIDER - string

Available options are: twilio, messagebird, textlocal, and vonage

Then you can use your twilio credentials:

  • SMS_TWILIO_ACCOUNT_SID
  • SMS_TWILIO_AUTH_TOKEN
  • SMS_TWILIO_MESSAGE_SERVICE_SID - can be set to your twilio sender mobile number

Or Messagebird credentials, which can be obtained in the Dashboard:

  • SMS_MESSAGEBIRD_ACCESS_KEY - your Messagebird access key
  • SMS_MESSAGEBIRD_ORIGINATOR - SMS sender (your Messagebird phone number with + or company name)

CAPTCHA

  • If enabled, CAPTCHA will check the request body for the captcha_token field and make a verification request to the CAPTCHA provider.

SECURITY_CAPTCHA_ENABLED - string

Whether captcha middleware is enabled

SECURITY_CAPTCHA_PROVIDER - string

for now the only options supported are: hcaptcha and turnstile

  • SECURITY_CAPTCHA_SECRET - string
  • SECURITY_CAPTCHA_TIMEOUT - string

Retrieve from hcaptcha or turnstile account

Reauthentication

SECURITY_UPDATE_PASSWORD_REQUIRE_REAUTHENTICATION - bool

Enforce reauthentication on password update.

Anonymous Sign-Ins

GOTRUE_EXTERNAL_ANONYMOUS_USERS_ENABLED - bool

Use this to enable/disable anonymous sign-ins.

Endpoints

Auth exposes the following endpoints:

GET /settings

Returns the publicly available settings for this auth instance.

{
  "external": {
    "apple": true,
    "azure": true,
    "bitbucket": true,
    "discord": true,
    "facebook": true,
    "figma": true,
    "github": true,
    "gitlab": true,
    "google": true,
    "keycloak": true,
    "linkedin": true,
    "notion": true,
    "slack": true,
    "spotify": true,
    "twitch": true,
    "twitter": true,
    "workos": true
  },
  "disable_signup": false,
  "autoconfirm": false
}

POST, PUT /admin/users/<user_id>

Creates (POST) or Updates (PUT) the user based on the user_id specified. The ban_duration field accepts the following time units: "ns", "us", "ms", "s", "m", "h". See time.ParseDuration for more details on the format used.

headers:
{
  "Authorization": "Bearer eyJhbGciOiJI...M3A90LCkxxtX9oNP9KZO" // requires a role claim that can be set in the GOTRUE_JWT_ADMIN_ROLES env var
}

body:
{
  "role": "test-user",
  "email": "[email protected]",
  "phone": "12345678",
  "password": "secret", // only if type = signup
  "email_confirm": true,
  "phone_confirm": true,
  "user_metadata": {},
  "app_metadata": {},
  "ban_duration": "24h" or "none" // to unban a user
}

POST /admin/generate_link

Returns the corresponding email action link based on the type specified. Among other things, the response also contains the query params of the action link as separate JSON fields for convenience (along with the email OTP from which the corresponding token is generated).

headers:
{
  "Authorization": "Bearer eyJhbGciOiJI...M3A90LCkxxtX9oNP9KZO" // admin role required
}

body:
{
  "type": "signup" or "magiclink" or "recovery" or "invite",
  "email": "[email protected]",
  "password": "secret", // only if type = signup
  "data": {
    ...
  }, // only if type = signup
  "redirect_to": "https://supabase.io" // Redirect URL to send the user to after an email action. Defaults to SITE_URL.

}

Returns

{
  "action_link": "http://localhost:9999/verify?token=TOKEN&type=TYPE&redirect_to=REDIRECT_URL",
  "email_otp": "EMAIL_OTP",
  "hashed_token": "TOKEN",
  "verification_type": "TYPE",
  "redirect_to": "REDIRECT_URL",
  ...
}

POST /signup

Register a new user with an email and password.

{
  "email": "[email protected]",
  "password": "secret"
}

returns:

{
  "id": "11111111-2222-3333-4444-5555555555555",
  "email": "[email protected]",
  "confirmation_sent_at": "2016-05-15T20:49:40.882805774-07:00",
  "created_at": "2016-05-15T19:53:12.368652374-07:00",
  "updated_at": "2016-05-15T19:53:12.368652374-07:00"
}

// if sign up is a duplicate then faux data will be returned
// as to not leak information about whether a given email
// has an account with your service or not

Register a new user with a phone number and password.

{
  "phone": "12345678", // follows the E.164 format
  "password": "secret"
}

Returns:

{
  "id": "11111111-2222-3333-4444-5555555555555", // if duplicate sign up, this ID will be faux
  "phone": "12345678",
  "confirmation_sent_at": "2016-05-15T20:49:40.882805774-07:00",
  "created_at": "2016-05-15T19:53:12.368652374-07:00",
  "updated_at": "2016-05-15T19:53:12.368652374-07:00"
}

if AUTOCONFIRM is enabled and the sign up is a duplicate, then the endpoint will return:

{
  "code":400,
  "msg":"User already registered"
}

POST /invite

Invites a new user with an email. This endpoint requires the service_role or supabase_admin JWT set as an Auth Bearer header:

e.g.

headers: {
  "Authorization" : "Bearer eyJhbGciOiJI...M3A90LCkxxtX9oNP9KZO"
}
{
  "email": "[email protected]"
}

Returns:

{
  "id": "11111111-2222-3333-4444-5555555555555",
  "email": "[email protected]",
  "confirmation_sent_at": "2016-05-15T20:49:40.882805774-07:00",
  "created_at": "2016-05-15T19:53:12.368652374-07:00",
  "updated_at": "2016-05-15T19:53:12.368652374-07:00",
  "invited_at": "2016-05-15T19:53:12.368652374-07:00"
}

POST /verify

Verify a registration or a password recovery. Type can be signup or recovery or invite and the token is a token returned from either /signup or /recover.

{
  "type": "signup",
  "token": "confirmation-code-delivered-in-email"
}

password is required for signup verification if no existing password exists.

Returns:

{
  "access_token": "jwt-token-representing-the-user",
  "token_type": "bearer",
  "expires_in": 3600,
  "refresh_token": "a-refresh-token",
  "type": "signup | recovery | invite"
}

Verify a phone signup or sms otp. Type should be set to sms.

{
  "type": "sms",
  "token": "confirmation-otp-delivered-in-sms",
  "redirect_to": "https://supabase.io",
  "phone": "phone-number-sms-otp-was-delivered-to"
}

Returns:

{
  "access_token": "jwt-token-representing-the-user",
  "token_type": "bearer",
  "expires_in": 3600,
  "refresh_token": "a-refresh-token"
}

GET /verify

Verify a registration or a password recovery. Type can be signup or recovery or magiclink or invite and the token is a token returned from either /signup or /recover or /magiclink.

query params:

{
  "type": "signup",
  "token": "confirmation-code-delivered-in-email",
  "redirect_to": "https://supabase.io"
}

User will be logged in and redirected to:

SITE_URL/#access_token=jwt-token-representing-the-user&token_type=bearer&expires_in=3600&refresh_token=a-refresh-token&type=invite

Your app should detect the query params in the fragment and use them to set the session (supabase-js does this automatically)

You can use the type param to redirect the user to a password set form in the case of invite or recovery, or show an account confirmed/welcome message in the case of signup, or direct them to some additional onboarding flow

POST /otp

One-Time-Password. Will deliver a magiclink or sms otp to the user depending on whether the request body contains an "email" or "phone" key.

If "create_user": true, user will not be automatically signed up if the user doesn't exist.

{
  "phone": "12345678" // follows the E.164 format
  "create_user": true
}

OR

// exactly the same as /magiclink
{
  "email": "[email protected]"
  "create_user": true
}

Returns:

{}

POST /magiclink (recommended to use /otp instead. See above.)

Magic Link. Will deliver a link (e.g. /verify?type=magiclink&token=fgtyuf68ddqdaDd) to the user based on email address which they can use to redeem an access_token.

By default Magic Links can only be sent once every 60 seconds

{
  "email": "[email protected]"
}

Returns:

{}

when clicked the magic link will redirect the user to <SITE_URL>#access_token=x&refresh_token=y&expires_in=z&token_type=bearer&type=magiclink (see /verify above)

POST /recover

Password recovery. Will deliver a password recovery mail to the user based on email address.

By default recovery links can only be sent once every 60 seconds

{
  "email": "[email protected]"
}

Returns:

{}

POST /token

This is an OAuth2 endpoint that currently implements the password and refresh_token grant types

query params:

?grant_type=password

body:

// Email login
{
  "email": "[email protected]",
  "password": "somepassword"
}

// Phone login
{
  "phone": "12345678",
  "password": "somepassword"
}

or

query params:

grant_type=refresh_token

body:

{
  "refresh_token": "a-refresh-token"
}

Once you have an access token, you can access the methods requiring authentication by settings the Authorization: Bearer YOUR_ACCESS_TOKEN_HERE header.

Returns:

{
  "access_token": "jwt-token-representing-the-user",
  "token_type": "bearer",
  "expires_in": 3600,
  "refresh_token": "a-refresh-token"
}

GET /user

Get the JSON object for the logged in user (requires authentication)

Returns:

{
  "id": "11111111-2222-3333-4444-5555555555555",
  "email": "[email protected]",
  "confirmation_sent_at": "2016-05-15T20:49:40.882805774-07:00",
  "created_at": "2016-05-15T19:53:12.368652374-07:00",
  "updated_at": "2016-05-15T19:53:12.368652374-07:00"
}

PUT /user

Update a user (Requires authentication). Apart from changing email/password, this method can be used to set custom user data. Changing the email will result in a magiclink being sent out.

{
  "email": "[email protected]",
  "password": "new-password",
  "phone": "+123456789",
  "data": {
    "key": "value",
    "number": 10,
    "admin": false
  }
}

Returns:

{
  "id": "11111111-2222-3333-4444-5555555555555",
  "email": "[email protected]",
  "email_change_sent_at": "2016-05-15T20:49:40.882805774-07:00",
  "phone": "+123456789",
  "phone_change_sent_at": "2016-05-15T20:49:40.882805774-07:00",
  "created_at": "2016-05-15T19:53:12.368652374-07:00",
  "updated_at": "2016-05-15T19:53:12.368652374-07:00"
}

If GOTRUE_SECURITY_UPDATE_PASSWORD_REQUIRE_REAUTHENTICATION is enabled, the user will need to reauthenticate first.

{
  "password": "new-password",
  "nonce": "123456"
}

GET /reauthenticate

Sends a nonce to the user's email (preferred) or phone. This endpoint requires the user to be logged in / authenticated first. The user needs to have either an email or phone number for the nonce to be sent successfully.

headers: {
  "Authorization" : "Bearer eyJhbGciOiJI...M3A90LCkxxtX9oNP9KZO"
}

POST /logout

Logout a user (Requires authentication).

This will revoke all refresh tokens for the user. Remember that the JWT tokens will still be valid for stateless auth until they expires.

GET /authorize

Get access_token from external oauth provider

query params:

provider=apple | azure | bitbucket | discord | facebook | figma | github | gitlab | google | keycloak | linkedin | notion | slack | spotify | twitch | twitter | workos

scopes=<optional additional scopes depending on the provider (email and name are requested by default)>

Redirects to provider and then to /callback

For apple specific setup see: https://github.com/supabase/auth#apple-oauth

GET /callback

External provider should redirect to here

Redirects to <GOTRUE_SITE_URL>#access_token=<access_token>&refresh_token=<refresh_token>&provider_token=<provider_oauth_token>&expires_in=3600&provider=<provider_name> If additional scopes were requested then provider_token will be populated, you can use this to fetch additional data from the provider or interact with their services

auth's People

Contributors

awalias avatar biilmann avatar bnjmnt4n avatar brycekahle avatar calavera avatar darora avatar dependabot[bot] avatar dsumer avatar eliwilliamson avatar erezrokah avatar github-actions[bot] avatar harryet avatar hf avatar icecream78 avatar imorente avatar inian avatar j0 avatar kangmingtay avatar karlseguin avatar kitop avatar kiwicopple avatar lashajini avatar mansueli avatar mateomorris avatar mraerino avatar rybit avatar sweatybridge avatar thorwebdev avatar vbrown608 avatar zshipko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

auth's Issues

Create User Account with Multiple Providers

Feature request: Allow a user to log in with multiple providers

Requirement

A user should be able to log in with more than one provider. For example:

  1. A user authenticates with Facebook and creates an account in my app.
  2. The user decides to quit Facebook.
  3. The user wants to log back into my app at a later time, but cannot. The user should be at minimum be able to "sign in with email" and enter their email address and a password, then verify their email, and get access to their user account.

Another example:

  1. User creates an account in my app with Google.
  2. User comes back a month later and can't remember which provider they used, so they try to log in with Facebook. They can't -- because they already have a Google-provider account.
  3. The user should be able to authenticate with Facebook now as well, assuming they use the same email address with both providers.

Firebase handles this, albeit not very elegantly. This is an opportunity to make a much more flexible authentication system.

Describe alternatives you've considered

At this time, it appears that you'd need to create a separate user account, which would not give the user access to data they have previously created inside my app.

Additional thoughts

If a change to the core user object isn't possible here, how about a table of user aliases at least, where a user can log in using a provider (even if it's not their "first" or "main" provider) then once logged in the credentials are set to that of the main account. Not super clean, but might be quicker to implement.

How to confim a new email address ?

Improve documentation

Describe the problem

When I update the email of a user account, I receive a "Confirm email address change" with a email_change_token.
What should I do with it? Which end point should use to validate the new e-mail?

Thank you

Ability to enable/disable users temporarily

We should add two endpoints accessible by the admin:

r.With(api.requireAdminCredentials).Post("/disable", api.DisableUser)
r.With(api.requireAdminCredentials).Post("/enable", api.EnableUser)

we would need an is_disabled column on the users table which is checked before a token is requested, and returns an error "this user has been disabled by the admin" if is true

Multi-factor authentication

I'm submitting a ...

  • feature request

Summary
MFA would be a very nice addition to the auth module.

Here are two standards that I think should be supported:

  • HOTP and TOTP (e.g Google Authenticator, FreeOTP)
  • FIDO U2F (e.g YubiKey, Google Titan Key)

Docker image not deployed

Chore

Describe the chore

In the latest release (https://github.com/supabase/gotrue/actions/runs/560510377) the docker image didn't deploy:

image

I tried re-running the GitHub action and it skipped the release.

I then tried on my local machine and I'm getting

storage/dial.go:71:36: not enough arguments in call to columns.ForStructWithAlias
	have (interface {}, string, string)
	want (interface {}, string, string, string)

https://github.com/netlify/gotrue/blob/f023c23d846c98fafc8e227608d6059fb02845df/storage/dial.go#L71

This is the same as what I saw on the logs for the GitHub action (before they were cleared)

magic link support

we can use the existing recovery flow as a base but something with better DX would be nice

Adding a delete user API

Currently there is no Gotrue method for deleting users.

We do have a delete user on the dashboard, but Copple says it directly removes the user from auth.users. We should support this directly in Gotrue so that others can call this via supabase-js and better for our audit trails, etc.

User request

support for facebook external auth?

Feature request

Is your feature request related to a problem? Please describe.

Our app would like to authenticate users via facebook and then pull a list of friends from that user.

Describe the solution you'd like

Ideally supabase can authenticate with facebook for us, and store an auth token in the database that we can use to pull data from facebook in a long running task somewhere on a daily interval.

Describe alternatives you've considered

The alternative is not really feasible using postgrest. There is a good amount of complicated client to server communication that I do not want to write in sql statements. That means the alternative we are using for now rolling our own rest server that talks to a postgres database

Additional context

facebook is an oauth provider https://en.wikipedia.org/wiki/List_of_OAuth_providers

Error messages allows malicious actors to probe if an account with a specific email exists.

Bug report

Describe the bug

When signing in, GoTrue can return different error messages:

  • No user found with this email
  • Invalid Password

This allows malicious actors to probe if an account with a specific email exists.
The same goes for the password recovery feature, where GoTrue can return User not found.

Expected behavior

When signing in, return a unified error message, e.g Invalid email or password.
When recovering a password, do not tell the user if the email is not associated with an account.

Anonymous Sign-in

Feature request

For letting users anonymously enter into the application, and then if they want to continue, they can upgrade their account.

Describe the solution you'd like

Ability to sign in without any credentials.

add GET route for /verify

so that people can verify directly with gotrue from their confirmation email

can use the POST doc as a spec but note that it does not need to support password reset since this needs to first to the user app for the end-user to choose a new password, and also passwords should not be passed a query params

image

Always redirect back to user site for recovery/magic link

Feature request

Currently, if a recovery/magic link is expired, supabase will show a json error which is not a good user experience. Rather we should redirect back to the merchant site with an error_description URL param maybe?

Additional context

Add any other context or screenshots about the feature request here.
image

App needs to know that Password Recovery happening

the password recovery flow logs the user in and redirects the user to <SITE_URL>#access_token..etc.

need to add a query param either inside gotrue server, to let the user's app know that it's a password recovery

magic link: improve responses

magic link currently returns sign in responses when user doesn't exist (access_token, or confirmation_sent_at etc.)

and returns nothing when user exists and magic link is sent, recover endpoint returns and empty json body {} so should standardize

Login/Magic link email redirection argument/url

Feature request

Is your feature request related to a problem? Please describe.

Right now, when getting a magic link or signup confirmation email, the link always sends the user to the site URL defined in the settings page. While this is great, I would like to be able to direct users to different parts of the app depending on where they are when login in/signing up.

Describe the solution you'd like

I can think of several ways of doing this.

  • right now, I could add a redirect_to field in the auth.users table, set it when I trigger the magic link/signup email and read it on the other side to send the user to the right place. This means 2 db writes per login/signup (one before, one after to clear the field) and seems a bit heavy and brittle (what if there is an error just after the field is cleared? the link in the email will not work anymore)
  • add an extra redirectTo parameter in the auth.signUp (or magic link) call, which would be passed on to the link in the email, and finally back to the page the user lands on (the site URL), so that the app can process this. so my siteURL could look like example.com/auth/postLogin?redirectTo=<theNextStep>

Describe alternatives you've considered

See above, I think the second option is much nicer and easier to manage (at least from my perspective ๐Ÿ˜‰ )

Additional context

Add any other context or screenshots about the feature request here.

Apple Login as an OAuth Provider

Feature request

Is your feature request related to a problem? Please describe.

When I go to auth/settings I see External Oauth Providers for Google, Github, Gitlab, and Bitbucket. My understanding is that for an ios app, you must also provide Apple as an oauth provider. Is this something you intend to support in Supabase?

Describe the solution you'd like

I would like to have Apple supported as an external Oauth Provider

Describe alternatives you've considered

From what I understand, apple's store guidelines require that if you allow another oauth provider you must support apple oauth. If I am building an app powered by supabase I would like to offer google oauth, but I want to make sure this is supported.

Additional context

OAuth Providers array in `user` object

Feature request

Is your feature request related to a problem? Please describe.

In app_metadata.provoder in the user object, currently we can only get what provider did the user signed up with and not all the provides that the user has connected.

Describe the solution you'd like

Instead of providing only the initial OAuth Provider, provide an array of all the providers user has used in the past.

{
  // ...
  "app_metadata": {
-   "provider": "github"
+   "providers": ["github", "gitlab"]
  },
  // ...
}

This could be a massive breaking change, so here's an alternative solution:

Provide the current OAuth Provider and Dev's can record it on the application side.

Describe alternatives you've considered

N/A

Additional context

This can be used to show which OAuth Provider the user has connected and if they want to disconnect a provider or connect more, similar to the following:

Screenshot_20210406-124145_Chrome
ref: GitLab profile settings

allow whitelisting multiple domains in supabase auth

Feature request

Is your feature request related to a problem? Please describe.

I want to use supabase auth both during development (http://localhost:3000) and production (https://myawesome.domain.com). But I can only set one 'site url' in the auth setting. I can't enable auth for both domains (dev and prod) at the same time.

Describe the solution you'd like

I want to be able to add two or more domains to 'site url', so that both the dev and prod domain can use supabase auth at the same time.

Describe alternatives you've considered

During development, I need to switch supabase auth 'site url' to my dev domain (http://localhost:3000), but this brings down my production website since people can't login anymore.

Ability to use custom domain on Google dialog

image

This may be possible already by setting up some endpoints on user app which forward to callback domains but need to test to verify but the main work would be adding the ability to set the env var GOTRUE_EXTERNAL_GOOGLE_REDIRECT_URI from the Supabase dashboard

Multiple origin whitelist

currently referrers are restricted to the origin (SITE_URL)

but mobile requirements mean that we need to be able to whitelist multiple domains via the supabase dashboard

Add scopes to Github OAuth

Related to this discussion.

We're using Firebase at the moment to sign up new users with 'Sign in with Github' and read/write to their repos. This is possible because Firebase lets you add scopes to the OAuth request so the user can grant additional permissions.

It looks like the current GoTrue Github scopes are hard-coded to just be the user's email.

I've tried doing a second trip to get the additional permissions manually (like repository.surf's workaround), but I'm hitting a wall.

I imagine the functionality in supabase-js might look like

const { user, session, error } = await supabase.auth.signIn({
  provider: 'github',
  providerOptions: {
    scope: 'repo admin:org'
  }
})

We're eager to migrate over to Supabase (love it so far), so let me know if there's anything I can do to help with this.

Enforce password minimum length

we don't want to be too opinionated on the password requirements, but it may be useful to have a basic requirement of min 6 characters

this should only be enforced when the caller is trying to set a password (since oauth rows won't need an associated password)

see: supabase/ui#137

chore: Set last_sign_in on access_token generation

last_sign_in exists in the auth schema (auth.users.last_sign_in) but is not set anywhere in gotrue

there is an opportunity to update this value each time an access_token is generated by gotrue

it will then be shown on the supabase dashboard since it's already hooked up to read this value from the DB

image

Return token links

Feature request

Is your feature request related to a problem? Please describe.

At the moment an invite handled by sending an email. It would be nice to:

  • return the invite link when the /invite route is called
  • optionally choose to send emails (eg, send by default, parameter to not send)

Additional context

Persist additional scopes provider_token

we recently added the ability to request additional scopes and return the provider_token,

we need to figure out the best way to persist this token so it can be used again later, perhaps in the app or user_metadata is a good place

alternatively add it in the auth schema as a table or column on auth.users

Are the server responses format documented? (email address is already used, password too short, etc).

Question

Additional context

From supabase/supabase#143

Are the server responses format documented ? If they are I couldn't find them otherwise they should definitely be added to the doc at some point. It would make it easier to display accurate errors to the user (e.g. this mail address is already used, password too short, etc).

Edit: To be clear I did find some documentation here but I'm interested in the format of errors which are not in the readme.

Magic link redirect adds &type=recovery

we should try and change this to type=magiclink in this case

not easy without making schema changes to add magic_link_sent_at but maybe we need to add this

improve recovery flow

currently recovery emails contain a link like:

<user-app>/?recovery_token=XXXXXXXX

which can then be used to do a:

image

but we can skip this step by embedding the verify link directly into the email

this may require a change in gotrue to allow making a /verify over GET

Auth: Update email account will not update the adress to log in

If you update the email adress with supabase.auth.update, it will not replace the old one but create a "new_email" element in your auth.user object.

Therefore, when you try to log in again with the new updated email, it will not work and you'll have to use the old one.

Standardize Error Responses across APIs

As suggested by Nicolo, we should standardize the error responses coming from GoTrue, postgres, and realtime (and any other/future APIs) so that it's better DX when writing a client,

We can make this change on the servers themselves, but since postgrest and gotrue are fully/partially external may be harder to change, it might be an option to transform the errors within the client libraries/supabase-js, could be messy?

Nicolo also dropped this as a reference: http://spec.openapis.org/oas/v3.0.3#openapi-specification

reduce MaxFrequency for magic links

the default is currently 15 mins, we should reduce the default and also make sure the error is returned to the user if it is tripped and a new token is not generated first (since it invalidates the previous token)

Azure AD external auth

Feature request

Is your feature request related to a problem? Please describe.

Our organization is standardized on the Azure stack and as such we are required to use Azure AD for auth.

Describe the solution you'd like

Ability to authenticate via Azure AD over OAuth.

Describe alternatives you've considered

An alternative is not really feasible using Supabase without some hackery. I suppose we could have some weird callback system through another auth system that works with Azure AD that then creates a user in Supabase but it's going to get messy quickly.

Additional context

Azure AD supports OAuth 2.0 - https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/auth-oauth2

verify endpoint improve error responses

verify token endpoint currently returns User not found if the token has expired, should instead return token expired error

or if not going to be called via API, then can also redirect to something like <SITE_URL>#error_description=token_expired

Auth webhook with link

Hi !

Would it be possible to have add a webhook on the auth setting so that we could send the email ourselves with the link passed as a parameter ?

Currently auth are different from my other emails because they're cannot be sent to same way my other emails are. I'm sure that I'm not the only one in this situation. Also, they're more frequently sent to spam than my normal ones because of the link and the smtp connection.

Internationalization for Authentication Email Templates

Feature request

Internationalization for Authentication Email Templates

The Authentication Email Templates should be made available for i18n internationalization so you can send an email in any language based on the current language or locale setting.

So instead of having one set of templates, you'd have one set for each language your application supports. I.e. "en", "es", "fr", "de".

To keep existing compatibility you could leave the existing templates alone as the "default templates" but override those with a language-specific version of a language or locale code is set.

Describe alternatives you've considered

The only alternative would be to write a completely separate system, using a third-party email system, to replicate the automated features for password reset, email confirmation, etc.

Additional context

While it's relatively easy to create an internationalized login screen with libraries such as Angular's @ngx-translate/core, it's pretty awkward for a Spanish speaking user to sign up on a Spanish page then get an English confirmation email.

add a /login endpoint

it should wrap the /token?grant_type=password functionality

this is just to provide a simplified endpoint to the user

Improve email change DX

current email change email is sent to user

  • add template to supabase dashboard
  • gotrue confirmation url should be a get request to users endpoint with the email_change_token as a query param, which is confirmed and returns a new valid login session (hence invalidating older refresh_tokens that may have been opened on the old email) this is current implemented here

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.