# `Slink.OAuth.Plug`
[🔗](https://github.com/wkirschbaum/slink/blob/v0.6.0/lib/slink/oauth/plug.ex#L1)

The OAuth redirect endpoint: turns Slack's `?code=…` callback into a stored
installation.

Mount it at the app's Redirect URL, give it a 1-arity `:install` callback,
and the code exchange is handled for you — your callback just persists the
result:

    forward "/slack/oauth/callback", to: Slink.OAuth.Plug,
      init_opts: [
        client_id: "1234.5678",
        client_secret: fn -> System.fetch_env!("SLACK_CLIENT_SECRET") end,
        install: fn %Slink.OAuth.Install{} = install ->
          MyApp.Installs.put(install.team_id, install.bot_token)
        end
      ]

Options:

  * `:client_id` (required) and `:client_secret` (required) — the app's
    client credentials (Basic Information page). The secret may be a 0-arity
    function, resolved per request (see the Phoenix compile-time pitfall in
    `Slink.EventsApi.Plug`).
  * `:install` (required) — called with the `Slink.OAuth.Install` after a
    successful exchange. Return `:ok` to finish the flow; `{:error, reason}`
    (or a raise) responds 500 without claiming success.
  * `:redirect_uri` — must match the authorize URL's, when one was used.
  * `:redirect_to` — where to send the installer's browser after success
    (302). Defaults to a minimal "app installed" page.
  * `:verify_state` — a 1-arity function receiving the redirect's `state`
    param (or `nil`); return `false` to reject the callback (403). Pair it
    with `authorize_url/1`'s `:state` to tie installs to a real session —
    without it, anyone can complete an install *they* initiated against your
    endpoint, which is usually harmless but worth closing on public apps.

The installer clicking "Cancel" on the consent screen arrives here as
`?error=access_denied`; that's answered with a friendly page, no callback.

---

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