I have managed to set up oauth2 for user registration and authentication using Google oauth2 API as provider.
My code for oauth2 provider callback looks like this:
def callback(conn, %{"provider" => provider, "code" => code}) do
client = get_token!(provider, code)
user = get_user!(provider, client)
user_params = %{
first_name: user.body["given_name"],
last_name: user.body["family_name"],
email: user.body["email"],
provider: "google"
}
changeset = User.changeset(%User{}, user_params)
create(conn, changeset, client)
end
def create(conn, changeset, client) do
case insert_or_update_user(changeset) do
{:ok, user} ->
conn
|> put_flash(:info, "Thank you for signing in!")
|> put_session(:current_user, user)
|> put_session(:access_token, client.token.access_token)
|> redirect(to: "/")
{:error, _reason} ->
conn
|> put_flash(:error, "Error signing in")
|> redirect(to: page_path(conn, :index))
end
end
defp insert_or_update_user(changeset) do
case Repo.get_by(User, email: changeset.changes.email) do
nil ->
Repo.insert(changeset)
user ->
{:ok, user}
end
end
As can be seen I am loading the user object by the email address provided by Google’s oauth2 and signs him into the site (put_session(:current_user, user)
) after loading him by the given email address.
Is this correct, secure and satisfactory?
At the same time I wonder, what is the use of the access_token
? Is it something that I need to store in the users tables and check for its validity on each subsegment resource request made by the user?