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 unlesspkce: true:pkce— set totruefor public apps, which authenticate with the app key alone and therefore have no secret:name— registered name, soMagpie.Client.new/1and 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 (default300):on_refresh— 1-arity function called with the newMagpie.Auth.Tokenafter 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
Returns a specification to start this module under a supervisor.
See Supervisor.
@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)
@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.
@spec start_link(keyword()) :: GenServer.on_start()
Starts the server.
See the module documentation for the supported options.
@spec token(GenServer.server()) :: Magpie.Auth.Token.t()
Returns the whole token currently held by the server, without refreshing.
Handy for inspecting the expiry or persisting the token on shutdown.