Open tensiondriven opened 2 years ago
Here is some explanation for future readers. Maybe someone could make a pull request from it, but there is really more conceptual info needed, because the code examples already exist elsewhere.
This elixir-samples repo is referenced from the elixir-google-api repo, which implements the support for Google Apis in an Elixir package. I'm not sure how relevant that package is in the context of GoogleCloudPlatform
, but that's what I ended up using, so maybe the explanation is still meaningful.
Elixir is mostly used on the backend, and the refresh token
is an OAuth concept. The OAuth flow contains a step where an end-user interaction is necessary through the UI in order for the end-user to give consent to the app to access the user's data. An Elixir server code running on the backend cannot present any UI to the user, especially because the user may not be there at the moment.
Because of that, all the server can do is refresh the access token
using the refresh token
to continue accessing the user's data, but it cannot obtain the refresh token
on its own. Instead a separate flow needs to be implemented on the client, which obtains the refresh token
and submits it to the server for future use.
In a scenario where a long-living server-side task runs periodically and accesses the Google API, one option is to obtain the refresh token
manually beforehand. As the refresh token
is valid until explicitly revoked, the task can use it to obtain the access token
every time it runs, and continue with the API. Otherwise, if the user can be interacted with through some UI, the client OAuth flow can be implemented there, and then it's all straightforward.
Long story short, for the server side it all starts when the refresh token
is already available. Then, as elixir-google-api
's readme suggests, the goth package can be used to enable the token refresh. Expanding a bit on goth
's own docs, here is how:
credentials =
%{
"client_id" => "...",
"client_secret" => "...",
"refresh_token" => "..."
}
Goth.start_link(name: MyApp.Goth, source: {:refresh_token, credentials, []})
Goth.fetch!(MyApp.Goth)
In case of success, the response payload should contain a valid access token
, which can be used to interact with the Google API. There are other ways to employ Goth as well, and it can also automatically refetch a new access token
when the current one is nearing expiration.
I have an offline task that needs to run periodically over a long time period, and my access token expires too quickly. I need to use a refresh token pattern to update the access token periodically, but documentation isn't clear.
Please add to the
auth
example the use of refresh token. Thanks!