Revoke old refresh token when doing a refresh token rotation

See
https://auth0.com/blog/securing-single-page-applications-with-refresh-token-rotation/
for details for instance

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2021-05-31 12:08:06 +02:00
parent fd28b4d410
commit 15b3940262
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773

View File

@ -31,7 +31,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
@doc """ @doc """
Return current logged-in user Return current logged-in user
""" """
def get_current_user(_parent, _args, %{context: %{current_user: user}}) do def get_current_user(_parent, _args, %{context: %{current_user: %User{} = user}}) do
{:ok, user} {:ok, user}
end end
@ -87,13 +87,13 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
@doc """ @doc """
Refresh a token Refresh a token
""" """
def refresh_token(_parent, %{refresh_token: refresh_token}, context) do def refresh_token(_parent, %{refresh_token: refresh_token}, _resolution) do
with {:ok, user, _claims} <- Auth.Guardian.resource_from_token(refresh_token), with {:ok, user, _claims} <- Auth.Guardian.resource_from_token(refresh_token),
{:ok, _old, {exchanged_token, _claims}} <- {:ok, _old, {exchanged_token, _claims}} <-
Auth.Guardian.exchange(refresh_token, ["access", "refresh"], "access"), Auth.Guardian.exchange(refresh_token, "refresh", "access"),
{:ok, refresh_token} <- Authenticator.generate_refresh_token(user), {:ok, new_refresh_token} <- Authenticator.generate_refresh_token(user),
{:ok, %User{}} <- update_user_login_information(user, context) do {:ok, _claims} <- Auth.Guardian.revoke(refresh_token) do
{:ok, %{access_token: exchanged_token, refresh_token: refresh_token}} {:ok, %{access_token: exchanged_token, refresh_token: new_refresh_token}}
else else
{:error, message} -> {:error, message} ->
Logger.debug("Cannot refresh user token: #{inspect(message)}") Logger.debug("Cannot refresh user token: #{inspect(message)}")