improvement: remove readme contents, add tutorial (#81)

This commit is contained in:
Zach Daniel 2023-01-26 09:26:14 -05:00 committed by GitHub
parent 0660a895dd
commit 7276165593
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 256 additions and 77 deletions

View file

@ -10,83 +10,11 @@ The `ash_authentication_phoenix` package extends
adding router helpers, plugs and behaviours that makes adding authentication to adding router helpers, plugs and behaviours that makes adding authentication to
an existing Ash-based Phoenix application dead easy. 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
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` hexdocs](https://hexdocs.pm/ash_authentication_phoenix) and for the [`main`
branch](https://team-alembic.github.io/ash_authentication_phoenix). 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. * 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). * Feel free to ask any questions on out [GitHub discussions page](https://github.com/team-alembic/ash_authentication_phoenix/discussions).
## Licence ## License
MIT MIT

View file

@ -5,7 +5,10 @@ config :git_ops,
changelog_file: "CHANGELOG.md", changelog_file: "CHANGELOG.md",
repository_url: "https://github.com/team-alembic/ash_authentication_phoenix", repository_url: "https://github.com/team-alembic/ash_authentication_phoenix",
manage_mix_version?: true, 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" version_tag_prefix: "v"
config :ash_authentication_phoenix, DevWeb.Endpoint, config :ash_authentication_phoenix, DevWeb.Endpoint,

View file

@ -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.