# `AshAuthentication.Plug`
[🔗](https://github.com/team-alembic/ash_authentication/blob/main/lib/ash_authentication/plug.ex#L5)

Generate an authentication plug.

Use in your app by creating a new module called `AuthPlug` or similar:

```elixir
defmodule MyAppWeb.AuthPlug do
  use AshAuthentication.Plug, otp_app: :my_app

  def handle_success(conn, _activity, user, _token) do
    conn
    |> store_in_session(user)
    |> send_resp(200, "Welcome back #{user.name}")
  end

  def handle_failure(conn, _activity, reason) do
    conn
    |> send_resp(401, "Better luck next time")
  end
end
```

### Using in Phoenix

In your Phoenix router you can add it:

```elixir
scope "/auth" do
  pipe_through :browser
  forward "/", MyAppWeb.AuthPlug
end
```

In order to load any authenticated users for either web or API users you can add the following to your router:

```elixir
import MyAppWeb.AuthPlug

pipeline :session_users do
  plug :load_from_session
end

pipeline :bearer_users do
  plug :load_from_bearer
end

scope "/", MyAppWeb do
  pipe_through [:browser, :session_users]

  live "/", PageLive, :home
end

scope "/api", MyAppWeb do
  pipe_through [:api, :bearer_users]

  get "/" ApiController, :index
end
```
### Using in a Plug application

```elixir
use Plug.Router

forward "/auth", to: MyAppWeb.AuthPlug
```

Note that you will need to include a bunch of other plugs in the pipeline to
do useful things like session and query param fetching.

# `activity`

```elixir
@type activity() :: {atom(), atom()}
```

# `token`

```elixir
@type token() :: String.t()
```

# `handle_failure`

```elixir
@callback handle_failure(Plug.Conn.t(), activity(), any()) :: Plug.Conn.t()
```

When there is any failure during authentication this callback is called.

Note that this includes not just authentication failures but potentially
route-not-found errors also.

The default implementation simply returns a 401 status with the message
"Access denied".  You almost definitely want to override this.

# `handle_success`

```elixir
@callback handle_success(
  Plug.Conn.t(),
  activity(),
  Ash.Resource.record() | nil,
  token() | nil
) ::
  Plug.Conn.t()
```

When authentication has been succesful, this callback will be called with the
conn, the successful activity, the authenticated resource and a token.

This allows you to choose what action to take as appropriate for your
application.

The default implementation calls `store_in_session/2` and returns a simple
"Access granted" message to the user.  You almost definitely want to override
this behaviour.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
