mirror of
https://github.com/team-alembic/ash_authentication_phoenix.git
synced 2024-09-19 21:13:52 +12:00
improvement: remove readme contents, add tutorial (#81)
This commit is contained in:
parent
0660a895dd
commit
7276165593
3 changed files with 256 additions and 77 deletions
80
README.md
80
README.md
|
@ -10,83 +10,11 @@ The `ash_authentication_phoenix` package extends
|
|||
adding router helpers, plugs and behaviours that makes adding authentication to
|
||||
an existing Ash-based Phoenix application dead easy.
|
||||
|
||||
## Warning
|
||||
|
||||
This is **beta** software. Please don't use it without talking to us!
|
||||
|
||||
## Installation
|
||||
|
||||
The package can be installed by adding `ash_authentication_phoenix` to your list
|
||||
of dependencies in `mix.exs`:
|
||||
|
||||
```elixir
|
||||
def deps do
|
||||
[
|
||||
{:ash_authentication_phoenix, "~> 1.4.4"}
|
||||
]
|
||||
end
|
||||
```
|
||||
|
||||
If you wish to use our default [Tailwind](https://tailwindcss.com/)-based
|
||||
components, you will need to add the path to `ash_authentication_phoenix`'s
|
||||
components in your `assets/tailwind.config.js`:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
content: [
|
||||
// Other paths.
|
||||
"../deps/ash_authentication_phoenix/**/*.ex"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
This package assumes that you have [Phoenix](https://phoenixframework.org/),
|
||||
[Ash](https://ash-hq.org/) and
|
||||
[AshAuthentication](https://github.com/team-alembic/ash_authentication)
|
||||
installed and configured. See their individual documentation for details.
|
||||
|
||||
This package is designed so that you can choose the level of customisation
|
||||
required. At the easiest level of configuration, you can just add the routes
|
||||
into your router:
|
||||
|
||||
```elixir
|
||||
defmodule MyAppWeb.Router do
|
||||
use MyAppWeb, :router
|
||||
use AshAuthentication.Phoenix.Router
|
||||
|
||||
pipeline :browser do
|
||||
# ...
|
||||
plug(:load_from_session)
|
||||
end
|
||||
|
||||
scope "/" do
|
||||
pipe_through :browser
|
||||
sign_in_route
|
||||
sign_out_route MyAppWeb.AuthController
|
||||
auth_routes_for MyApp.Accounts.User, to: MyAppWeb.AuthController
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
This will give you a generic sign-in/registration page and store the
|
||||
authenticated user in the Phoenix session.
|
||||
|
||||
### Customisation
|
||||
|
||||
There are several methods of customisation available depending on the level of
|
||||
control you would like:
|
||||
|
||||
1. Use the [generic sign-in liveview](https://hexdocs.pm/ash_authentication_phoenix/AshAuthentication.Phoenix.SignInLive.html).
|
||||
2. Apply [overrides](https://hexdocs.pm/ash_authentication_phoenix/AshAuthentication.Phoenix.Overrides.html)
|
||||
to set your own CSS classes for all components.
|
||||
3. Build your own sign-in pages using the pre-defined components.
|
||||
4. Build your own sign-in pages using the generated `auth` routes.
|
||||
|
||||
## Documentation
|
||||
|
||||
Documentation for the latest release will be [available on
|
||||
See the [official documentation](https://ash-hq.org) for more.
|
||||
|
||||
Additionally, documentation for the latest release will be [available on
|
||||
hexdocs](https://hexdocs.pm/ash_authentication_phoenix) and for the [`main`
|
||||
branch](https://team-alembic.github.io/ash_authentication_phoenix).
|
||||
|
||||
|
@ -96,6 +24,6 @@ branch](https://team-alembic.github.io/ash_authentication_phoenix).
|
|||
* Please use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) - this allows us to dynamically generate the changelog.
|
||||
* Feel free to ask any questions on out [GitHub discussions page](https://github.com/team-alembic/ash_authentication_phoenix/discussions).
|
||||
|
||||
## Licence
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
|
|
@ -5,7 +5,10 @@ config :git_ops,
|
|||
changelog_file: "CHANGELOG.md",
|
||||
repository_url: "https://github.com/team-alembic/ash_authentication_phoenix",
|
||||
manage_mix_version?: true,
|
||||
manage_readme_version: "README.md",
|
||||
manage_readme_version: [
|
||||
"README.md",
|
||||
"documentation/tutorials/getting-started-with-ash-authentication-phoenix.md"
|
||||
],
|
||||
version_tag_prefix: "v"
|
||||
|
||||
config :ash_authentication_phoenix, DevWeb.Endpoint,
|
||||
|
|
|
@ -0,0 +1,248 @@
|
|||
# Getting Started Ash Authentication Phoenix
|
||||
|
||||
This guide assumes that you already have an Phoenix application set up with Ash.
|
||||
If you don't then check out the [Phoenix topic on Ash
|
||||
HQ](https://ash-hq.org/docs/guides/ash/latest/topics/phoenix).
|
||||
|
||||
|
||||
## Before continuing
|
||||
|
||||
If you haven't already, read and follow [Getting Started with Ash Authentication](https://ash-hq.org/docs/guides/ash_authentication/latest/tutorials/getting-started-with-authentication). You will use the things you create there in this tutorial.
|
||||
|
||||
## Add to your application's dependencies
|
||||
|
||||
```elixir
|
||||
# mix.exs
|
||||
|
||||
defp deps()
|
||||
[
|
||||
# ...
|
||||
{:ash_authentication_phoenix, "~> 1.4.4"}
|
||||
]
|
||||
end
|
||||
```
|
||||
|
||||
Add `ash_authentication_phoenix` to your `.formatter.exs`:
|
||||
|
||||
```elixir
|
||||
# .formatter.exs
|
||||
|
||||
[
|
||||
# ...
|
||||
import_deps: [:ash_authentication_phoenix]
|
||||
]
|
||||
```
|
||||
|
||||
## Phoenix 1.7 compatibility
|
||||
|
||||
In `your_app_web.ex` you will need to change `helpers: false` to `helpers: true` in the router section. AshAuthenticationPhoenix relies on
|
||||
these helpers to know where your authenticated routes are.
|
||||
|
||||
## `AshAuthentication.Phoenix.Router`
|
||||
|
||||
`ash_authentication_phoenix` includes several helper macros which can generate
|
||||
Phoenix routes for you. They are included by way of a `use` macro:
|
||||
|
||||
```elixir
|
||||
# lib/my_app_web/router.ex
|
||||
|
||||
defmodule MyAppWeb.Router do
|
||||
use MyAppWeb, :router
|
||||
use AshAuthentication.Phoenix.Router
|
||||
|
||||
pipeline :browser do
|
||||
# ...
|
||||
plug(:load_from_session)
|
||||
end
|
||||
|
||||
pipeline :api do
|
||||
# ...
|
||||
plug(:load_from_bearer)
|
||||
end
|
||||
|
||||
scope "/", MyAppWeb do
|
||||
pipe_through :browser
|
||||
sign_in_route
|
||||
sign_out_route AuthController
|
||||
auth_routes_for MyApp.Accounts.User, to: AuthController
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### `AshAuthentication.Phoenix.Router.sign_in_route/3`
|
||||
|
||||
This helper generates a live route to the `AshAuthentication.Phoenix.SignInLive`
|
||||
LiveView. This LiveView renders a generic sign-in/register screen. It is
|
||||
entirely optional, and can be customised either by way of `AshAuthentication.Phoenix.Overrides` or replaced entirely.
|
||||
|
||||
### `AshAuthentication.Phoenix.Router.sign_out_route/3`
|
||||
|
||||
This helper generates a route which points to the `sign_out` action in your `AuthController`.
|
||||
|
||||
### `AshAuthentication.Phoenix.Router.auth_routes_for/2`
|
||||
|
||||
This helper generates all the required routes for all strategies supported by the provided resource.
|
||||
|
||||
### Generated routes
|
||||
|
||||
Given the above configuration you should see the following in your routes:
|
||||
|
||||
```
|
||||
# mix phx.routes
|
||||
|
||||
auth_path * /auth/user/confirm MyAppWeb.AuthController {:user, :confirm, :confirm}
|
||||
auth_path * /auth/user/password/register MyAppWeb.AuthController {:user, :password, :register}
|
||||
auth_path * /auth/user/password/sign_in MyAppWeb.AuthController {:user, :password, :sign_in}
|
||||
auth_path * /auth/user/password/reset_request MyAppWeb.AuthController {:user, :password, :reset_request}
|
||||
auth_path * /auth/user/password/reset MyAppWeb.AuthController {:user, :password, :reset}
|
||||
auth_path GET /sign-in AshAuthentication.Phoenix.SignInLive :sign_in
|
||||
auth_path GET /sign-out MyAppWeb.AuthController :sign_out
|
||||
```
|
||||
|
||||
## `AshAuthentication.Phoenix.Controller`
|
||||
|
||||
Instead of using `AshAuthentication.Plug` as
|
||||
suggested in [the previous guide](/documentation/tutorials/getting-started-with-authentication.md),
|
||||
`ash_authentication_phoenix` comes with a generator which creates a
|
||||
`Phoenix.Controller` by way of a `use` macro.
|
||||
|
||||
All functions in `AshAuthentication.Phoenix.Plug` are automatically imported.
|
||||
|
||||
You can define multiple versions if required (eg one for your `:api` pipeline
|
||||
and another for your `:browser` pipeline). Let's define a version for a browser
|
||||
client:
|
||||
|
||||
> Remember to define an appropriate template in `failure.html.heex` for your
|
||||
> controller. Alternatively, you could redirect with a flash message.
|
||||
|
||||
```elixir
|
||||
# lib/my_app_web/controllers/auth_controller.ex
|
||||
|
||||
defmodule MyAppWeb.Controllers.AuthController do
|
||||
use MyAppWeb, :controller
|
||||
use AshAuthentication.Phoenix.Controller
|
||||
|
||||
def success(conn, _activity, user, _token) do
|
||||
return_to = get_session(conn, :return_to) || Routes.path_path(conn, :index)
|
||||
|
||||
conn
|
||||
|> delete_session(:return_to)
|
||||
|> store_in_session(user)
|
||||
|> assign(:current_user, user)
|
||||
|> redirect(to: return_to)
|
||||
end
|
||||
|
||||
def failure(conn, _activity, _reason) do
|
||||
conn
|
||||
|> put_status(401)
|
||||
|> render("failure.html")
|
||||
end
|
||||
|
||||
def sign_out(conn, _params) do
|
||||
return_to = get_session(conn, :return_to) || Routes.path_path(conn, :index)
|
||||
|
||||
conn
|
||||
|> clear_session()
|
||||
|> redirect(to: return_to)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
### `success/4`
|
||||
|
||||
This callback is called when registration or sign-in is successful. You should
|
||||
use it to prepare a response back to the user indicating that authentication was
|
||||
successful.
|
||||
|
||||
It is called with the following arguments:
|
||||
|
||||
* `conn` the Plug connection.
|
||||
* `activity` a tuple containing two atoms - the strategy name and the phase.
|
||||
You can use this if you need to provide different behaviour depending on the
|
||||
authentication method.
|
||||
* `user` the authenticated user record (ie an instance of your user resource).
|
||||
* `token` a string containing a JWT for this user, if tokens are enabled.
|
||||
Otherwise `nil`.
|
||||
|
||||
In the example above we set up the session to know who the user is on their next
|
||||
request and redirect them to an appropriate location.
|
||||
|
||||
### `failure/3`
|
||||
|
||||
This callback is called when registration or sign-in is unsuccessful. You
|
||||
should use this to render an error, or provide some other indication to the user
|
||||
that authentication has failed.
|
||||
|
||||
It is called with the following arguments:
|
||||
|
||||
* `conn` the Plug connection.
|
||||
* `activity` a tuple containing two atoms - the strategy name and the phase.
|
||||
You can use this if you need to provide different behaviour depending on the
|
||||
authentication method.
|
||||
* The reason for failure. It _could_ be an `Ash.Error`, an `Ash.Changeset`,
|
||||
or any other failure.
|
||||
|
||||
In the example above we simply set the HTTP status to 401 and render an HTML page.
|
||||
|
||||
### `sign_out/2`
|
||||
|
||||
This is not strictly necessary, but if you have enabled the
|
||||
`AshAuthentication.Phoenix.Router.sign_out_route/3`
|
||||
helper in your router, then this is the controller action which will be called.
|
||||
Use this to perform any sign-out actions (like clearing the session or `AshAuthentication.Phoenix.Plug.revoke_bearer_tokens/2` and then sending the user on their way.
|
||||
|
||||
## Component library
|
||||
|
||||
`ash_authentication_phoenix` ships with a number of components allowing you to
|
||||
pick the level of customisation you require.
|
||||
|
||||
* `AshAuthentication.Phoenix.Components.SignIn`
|
||||
This is the top-level component, given a [resource
|
||||
configuration](t:AshAuthentication.resource_config) it will iterate through
|
||||
all the configured authentication providers and render their UI. You can
|
||||
place this directly into your sign-in page if you want.
|
||||
* `AshAuthentication.Phoenix.Components.Password`
|
||||
This component renders the UI for password authentication - both the
|
||||
registration and sign-in UI.
|
||||
* `AshAuthentication.Phoenix.Components.Password.SignInForm`
|
||||
This component renders the UI for a password authentication sign-in form.
|
||||
* `AshAuthentication.Phoenix.Components.Password.RegisterForm`
|
||||
This component renders the UI for a password authentication registration
|
||||
form.
|
||||
* `AshAuthentication.Phoenix.Components.Password.ResetForm`
|
||||
This component renders the UI for a user to request a password reset.
|
||||
* `AshAuthentication.Phoenix.Components.Password.Input`
|
||||
This module contains several function components which provide individual
|
||||
input fields and buttons for password authentication.
|
||||
* `AshAuthentication.Phoenix.Components.OAuth2`
|
||||
A component which renders a sign-in button for an OAuth 2.0 provider.
|
||||
|
||||
### Overrides
|
||||
|
||||
All the components above and the `AshAuthentication.Phoenix.SignInLive`
|
||||
LiveView are customisable via the `AshAuthentication.Phoenix.Overrides`
|
||||
system.
|
||||
|
||||
Overrides allow you to configure CSS classes and other options for the
|
||||
components without needing to modify them.
|
||||
|
||||
### Tailwind
|
||||
|
||||
If you plan on using our default [Tailwind](https://tailwindcss.com/)-based
|
||||
components without overriding them you will need to modify your
|
||||
`assets/tailwind.config.js` to include the `ash_authentication_phoenix`
|
||||
dependency:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
content: [
|
||||
// Other paths.
|
||||
"../deps/ash_authentication_phoenix/**/*.ex"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
In this guide we've learned how to add Ash Authentication to Phoenix, configure
|
||||
routes and handle authentication.
|
Loading…
Reference in a new issue