How to access the auth token of a signed in Oauth2 user

I am working to make an app that uses Google sign in, but I also want to be able to use their token to work with Google Apis. I am not sure how to access the token though using Ash Framework.

It looks like I would need to use the AshAuthentication.UserIdentity but when a user logs in I don’t see anything being created in those relavent tables. I am not sure if it matters but I added the UserIdentity after the user was already created.

Could anyone please point me in the right direction on how to go about this?

  actions do
    defaults [:read]

    create :register_with_google do
      argument :user_info, :map, allow_nil?: false
      argument :oauth_tokens, :map, allow_nil?: false
      # map includes id token and access token
      upsert? true
      upsert_identity :unique_email

      change AshAuthentication.GenerateTokenChange

      # Required if you have the `identity_resource` configuration enabled.
      change AshAuthentication.Strategy.OAuth2.IdentityChange

      change fn changeset, _ctx ->
        IO.inspect(changeset, label: "changeset")
        user_info = Ash.Changeset.get_argument(changeset, :user_info)
        IO.inspect(user_info, label: "user info")

        changeset
        |> Ash.Changeset.change_attribute(:email, user_info["email"])
      end
    end

Hi @ashkan117, welcome :wave:

It looks to me like you’re doing it correctly, but I think I remember someone telling me recently that Google only provides the refresh token the first time a user authenticates. Could this be the issue?

I see that you’re inspecting the changeset - you should see the after_action hook added by AshAuthentication.Strategy.OAuth2.IdentityChange correct?

Hi @jimsynz and thanks.

It looks like Google does return the access and refresh token

 oauth_tokens: %{                   
      "access_token" => "...",                                                                      
      "expires_in" => 3599,                 
      "id_token" => "...",
      "refresh_token" => "...",

I don’t see the after_action hook tied to the changeset though. Would this just be an additional field?

Yeah, you should see a list of functions in the after_action field.

Quick question - do you have the identity_resource option set in your strategy DSL?

I did not have the identity_resource in my authentication strategy. Adding that fixed it.

I didn’t see the option earlier in the docs.

  authentication do
    api Alpen.Accounts

    strategies do
      oauth2 :google do
        ...
        identity_resource Alpen.Accounts.UserIdentity
      end
    end
  end

It did complain that I needed to add the UserIdentity module to a resource registry but after adding that it worked.

entries do
   ...
    entry Alpen.Accounts.UserIdentity
end

Thank you for pointing that out!

Would the appropriate way to interact with the access_tokens in the UserIdentity then be through some custom defined code acounts?

I’m glad you got it sorted out :tada:

I’m not sure I follow. Can you rephrase the question?