2023-01-18 11:16:20 +13:00
|
|
|
# Auth0 Quick Start Guide
|
|
|
|
|
|
|
|
This is a _very quick_ tutorial on how to configure your application to use
|
|
|
|
Auth0 for authentication.
|
|
|
|
|
2023-09-29 03:26:42 +13:00
|
|
|
Before you start this tutorial, skip the Token resource while following the
|
|
|
|
[AshAuthenticationPhoenix guide](https://hexdocs.pm/ash_authentication_phoenix/getting-started-with-ash-authentication-phoenix.html))
|
|
|
|
|
2024-03-28 14:39:53 +13:00
|
|
|
> [!WARNING]
|
2024-01-29 14:23:25 +13:00
|
|
|
> Make sure that your `ash_postgres` dependency is `~> 1.3.64`. A bug in previous versions prevents the action shown below from working correctly.
|
|
|
|
|
2023-09-29 03:26:42 +13:00
|
|
|
Next, you need to configure an application in [the Auth0
|
2023-01-18 11:16:20 +13:00
|
|
|
dashboard](https://manage.auth0.com/) using the following steps:
|
|
|
|
|
2024-03-28 14:39:53 +13:00
|
|
|
1. Click "Create Application".
|
|
|
|
2. Set your application name to something that identifies it. You will likely
|
|
|
|
need separate applications for development and production environments, so
|
|
|
|
keep that in mind.
|
|
|
|
3. Select "Regular Web Application" and click "Create".
|
|
|
|
4. Switch to the "Settings" tab.
|
|
|
|
5. Copy the "Domain", "Client ID" and "Client Secret" somewhere safe - we'll
|
|
|
|
need them soon.
|
|
|
|
6. In the "Allowed Callback URLs" section, add your callback URL. The
|
|
|
|
callback URL is generated from the following information:
|
|
|
|
|
|
|
|
- The base URL of the application - in development that would be
|
|
|
|
`http://localhost:4000/` but in production will be your application's
|
|
|
|
URL.
|
|
|
|
- The mount point of the auth routes in your router - we'll assume
|
|
|
|
`/auth`.
|
|
|
|
- The "subject name" of the resource being authenticated - we'll assume `user`.
|
|
|
|
- The name of the strategy in your configuration. By default this is
|
|
|
|
`auth0`.
|
|
|
|
|
|
|
|
This means that the callback URL should look something like
|
|
|
|
`http://localhost:4000/auth/user/auth0/callback`.
|
|
|
|
|
|
|
|
7. Set "Allowed Web Origins" to your application's base URL.
|
|
|
|
8. Click "Save Changes".
|
2023-01-18 11:16:20 +13:00
|
|
|
|
2023-09-29 03:26:42 +13:00
|
|
|
Next we can configure our resource:
|
2023-01-18 11:16:20 +13:00
|
|
|
|
|
|
|
```elixir
|
|
|
|
defmodule MyApp.Accounts.User do
|
2024-03-28 14:39:53 +13:00
|
|
|
use Ash.Resource,
|
|
|
|
extensions: [AshAuthentication],
|
|
|
|
domain: MyApp.Accounts
|
2023-01-18 11:16:20 +13:00
|
|
|
|
|
|
|
authentication do
|
2023-01-19 13:10:33 +13:00
|
|
|
strategies do
|
|
|
|
auth0 do
|
|
|
|
client_id MyApp.Secrets
|
|
|
|
redirect_uri MyApp.Secrets
|
|
|
|
client_secret MyApp.Secrets
|
2023-11-22 10:58:06 +13:00
|
|
|
base_url MyApp.Secrets
|
2023-01-19 13:10:33 +13:00
|
|
|
end
|
2023-01-18 11:16:20 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
Because all the configuration values should be kept secret (ie the
|
|
|
|
`client_secret`) or are likely to be different for each environment we use the
|
|
|
|
`AshAuthentication.Secret` behaviour to provide them. In this case we're
|
|
|
|
delegating to the OTP application environment, however you may want to use a
|
|
|
|
system environment variable or some other secret store (eg Vault).
|
|
|
|
|
|
|
|
```elixir
|
|
|
|
defmodule MyApp.Secrets do
|
|
|
|
use AshAuthentication.Secret
|
|
|
|
|
|
|
|
def secret_for([:authentication, :strategies, :auth0, :client_id], MyApp.Accounts.User, _) do
|
|
|
|
get_config(:client_id)
|
|
|
|
end
|
|
|
|
|
|
|
|
def secret_for([:authentication, :strategies, :auth0, :redirect_uri], MyApp.Accounts.User, _) do
|
|
|
|
get_config(:redirect_uri)
|
|
|
|
end
|
|
|
|
|
|
|
|
def secret_for([:authentication, :strategies, :auth0, :client_secret], MyApp.Accounts.User, _) do
|
|
|
|
get_config(:client_secret)
|
|
|
|
end
|
|
|
|
|
2023-11-22 10:58:06 +13:00
|
|
|
def secret_for([:authentication, :strategies, :auth0, :base_url], MyApp.Accounts.User, _) do
|
|
|
|
get_config(:base_url)
|
2023-01-18 11:16:20 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
defp get_config(key) do
|
|
|
|
:my_app
|
2023-09-29 03:27:22 +13:00
|
|
|
|> Application.fetch_env!(:auth0)
|
|
|
|
|> Keyword.fetch!(key)
|
|
|
|
|> then(&{:ok, &1})
|
2023-01-18 11:16:20 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
```
|
|
|
|
|
|
|
|
The values for this configuration should be:
|
|
|
|
|
2024-03-28 14:39:53 +13:00
|
|
|
- `client_id` - the client ID copied from the Auth0 settings page.
|
|
|
|
- `redirect_uri` - the URL to the generated auth routes in your application
|
|
|
|
(eg `http://localhost:4000/auth`).
|
|
|
|
- `client_secret` the client secret copied from the Auth0 settings page.
|
|
|
|
- `base_url` - the "domain" value copied from the Auth0 settings page prefixed
|
|
|
|
with `https://` (eg `https://dev-yu30yo5y4tg2hg0y.us.auth0.com`).
|
2023-01-18 12:04:03 +13:00
|
|
|
|
2024-03-28 14:39:53 +13:00
|
|
|
Lastly, we need to add a register action to your user resource. This is defined
|
2023-01-18 12:04:03 +13:00
|
|
|
as an upsert so that it can register new users, or update information for
|
2024-03-28 14:39:53 +13:00
|
|
|
returning users. The default name of the action is `register_with_` followed by
|
|
|
|
the strategy name. In our case that is `register_with_auth0`.
|
2023-01-18 12:04:03 +13:00
|
|
|
|
|
|
|
The register action takes two arguments, `user_info` and the `oauth_tokens`.
|
2024-03-28 14:39:53 +13:00
|
|
|
|
|
|
|
- `user_info` contains the [`GET /userinfo` response from
|
|
|
|
Auth0](https://auth0.com/docs/api/authentication#get-user-info) which you
|
|
|
|
can use to populate your user attributes as needed.
|
|
|
|
- `oauth_tokens` contains the [`POST /oauth/token` response from
|
|
|
|
Auth0](https://auth0.com/docs/api/authentication#get-token) - you may want
|
|
|
|
to store these if you intend to call the Auth0 API on behalf of the user.
|
2023-01-18 12:04:03 +13:00
|
|
|
|
|
|
|
```elixir
|
|
|
|
defmodule MyApp.Accounts.User do
|
2024-03-28 14:39:53 +13:00
|
|
|
use Ash.Resource,
|
|
|
|
extensions: [AshAuthentication],
|
|
|
|
domain: MyApp.Accounts
|
2023-01-18 12:04:03 +13:00
|
|
|
|
|
|
|
# ...
|
|
|
|
|
|
|
|
actions do
|
|
|
|
create :register_with_auth0 do
|
|
|
|
argument :user_info, :map, allow_nil?: false
|
|
|
|
argument :oauth_tokens, :map, allow_nil?: false
|
|
|
|
upsert? true
|
2023-09-29 03:26:42 +13:00
|
|
|
upsert_identity :unique_email
|
2023-01-18 12:04:03 +13:00
|
|
|
|
|
|
|
# Required if you have token generation enabled.
|
|
|
|
change AshAuthentication.GenerateTokenChange
|
|
|
|
|
|
|
|
# Required if you have the `identity_resource` configuration enabled.
|
|
|
|
change AshAuthentication.Strategy.OAuth2.IdentityChange
|
|
|
|
|
|
|
|
change fn changeset, _ ->
|
|
|
|
user_info = Ash.Changeset.get_argument(changeset, :user_info)
|
|
|
|
|
|
|
|
Ash.Changeset.change_attributes(changeset, Map.take(user_info, ["email"]))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# ...
|
|
|
|
|
|
|
|
end
|
|
|
|
```
|