Magpie.Auth.TokenServer (Magpie v0.2.0)

Copy Markdown View Source

A Magpie.Auth.TokenProvider that keeps an access token fresh.

Holds the current Magpie.Auth.Token plus the credentials needed to renew it, and refreshes it a few minutes before it expires — so requests never wait on a token that Dropbox is about to reject.

Put it in your supervision tree and hand its name to the client:

children = [
  {Magpie.Auth.TokenServer,
   name: MyApp.DropboxToken,
   app_key: System.fetch_env!("DROPBOX_APP_KEY"),
   app_secret: System.fetch_env!("DROPBOX_APP_SECRET"),
   refresh_token: System.fetch_env!("DROPBOX_REFRESH_TOKEN")}
]

client = Magpie.Client.new(token_provider: {Magpie.Auth.TokenServer, MyApp.DropboxToken})

Options

  • :app_key — your Dropbox app key (required)
  • :refresh_token — the long-lived refresh token (required)
  • :app_secret — your app secret. Required unless pkce: true
  • :pkce — set to true for public apps, which authenticate with the app key alone and therefore have no secret
  • :name — registered name, so Magpie.Client.new/1 and your supervision tree can refer to the server without carrying its pid
  • :access_token / :expires_at — an access token you already have, to avoid a refresh on the first call. Pass both or neither: a token without a known expiry is refreshed right away
  • :refresh_margin — how many seconds before expiry a token is considered stale (default 300)
  • :on_refresh — 1-arity function called with the new Magpie.Auth.Token after every successful refresh, e.g. to persist it

Concurrency

Refreshes happen inside the server, so concurrent callers queue behind a single HTTP request — a burst of requests can never trigger a burst of refreshes. When a refresh fails the server keeps its previous state and replies {:error, %Magpie.Error{}} to the caller instead of crashing: a temporarily unreachable Dropbox should not take your supervision tree down, and the next call simply tries again.

Summary

Functions

Returns a specification to start this module under a supervisor.

Returns the current access token, refreshing it first when it is expired or within :refresh_margin seconds of expiring.

Forces a refresh and returns the new access token.

Starts the server.

Returns the whole token currently held by the server, without refreshing.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

fetch_token(server)

@spec fetch_token(GenServer.server()) ::
  {:ok, String.t()} | {:error, Magpie.Error.t()}

Returns the current access token, refreshing it first when it is expired or within :refresh_margin seconds of expiring.

{:ok, access_token} = Magpie.Auth.TokenServer.fetch_token(MyApp.DropboxToken)

refresh_token(server)

@spec refresh_token(GenServer.server()) ::
  {:ok, String.t()} | {:error, Magpie.Error.t()}

Forces a refresh and returns the new access token.

Magpie calls this for you when Dropbox rejects a token as expired; you rarely need to call it yourself.

start_link(opts)

@spec start_link(keyword()) :: GenServer.on_start()

Starts the server.

See the module documentation for the supported options.

token(server)

Returns the whole token currently held by the server, without refreshing.

Handy for inspecting the expiry or persisting the token on shutdown.