We've moved discussions to Discord

User_Connected_Account tokens are encrypted?

Ugurcan Kaya
In user connected accounts model there are four values  Chris Oliver  

      t.string :encrypted_access_token
      t.string :encrypted_access_token_iv
      t.string :encrypted_access_token_secret
      t.string :encrypted_access_token_secret_iv

how do we retrieve actual token values to use in an API call? 

connected_account.access_token returns the true value
connected_account.access_token_secret seems always nil

I am testing with Twitter.

What am I missing here? 
Chris Oliver
Hmm, sounds like something wrong. I'll check this when I'm back from a couple errands.

Basically, you have these three things:

  1. User::ConnectedAccount stores a copy of the access token and the secret encrypted in the database. It encrypts it because they're basically passwords for other services.
  2. To retrieve an access token from a record, you should be able to use "@account.access_token"
  3. We provide a special "@account.token" method that will seamlessly refresh the token for you if it expires. This way you don't have to worry about expired tokens.

If your "access_token" is returning true, then it sounds like something is wrong. Twitter might have changed on me since I last tested it.
Chris Oliver
Testing this myself, it saves the access_token correctly, but it's missing the access_token_secret for some reason. I'm investigating that.
Ugurcan Kaya
Chris Oliver thanks! From what I see auth hash returns the secret but it does not get saved for some reason.

How does @accont.token method refresh the expired tokens by the way? Most services have different endpoints for token refreshing, how is that standardized as part of OAuth process? 

Does it just work for Twitter & Facebook or for all omniauth strategies?

Chris Oliver
You can read the source code for the refresh in the model. 👍

Alright, I have a fix for the access_token_secret issue. Replace the "access_token_secret=" method in the model with the following.

  # Safely handles empty strings before attempting encryption
  def safe_access_token_secret=(value)
    return if value.blank?
    __send__("attr_encrypted_access_token_secret=", value)
  end

  # Replace the dynamically defined attr_encrypted method with our own
  alias_method :attr_encrypted_access_token_secret=, :access_token_secret=
  alias_method :access_token_secret=, :safe_access_token_secret=

I've also added a test to make sure this can be assigned

The issue is basically that the encryptor gem doesn't let you encrypt empty strings. I was trying to handle that safely so it wouldn't crash if you assigned "" to the access_token_secret.
Chris Oliver
Just pushed all this code up to the git repo if you want to check it out there.
Ugurcan Kaya
Chris Oliver     

There is a token method in the connected_accounts model that seems like updating the token every time the user logs in, right? 🤔  

But it would not refresh the token on the fly if I just call the @account.token method in a controller? That's actually what I meant to ask. There is a chance that the token may have expired just before an API call in a controller if a user did not log in with that account for a while. 

For some reason, I had that expectation from the token method after reading the jumpstart documentation 😛

perhaps another default helper method may be useful to everyone, something like  

def token_expiring?
 if expires_at? && expires_at <= Time.zone.now + 7.days
end

will try the fix in a bit, thanks so much for the hard work  👍 

Chris Oliver
Yes, if they login, it'll update the token again. I don't know if that always returns a new token or not.

ConnectedAccount keeps track of the expires_at and the "token" method will renew it if it's expired. There's a small chance the token could be expiring in the next second and the next API call may fail with an expired token.

We can refactor that to account for that case.
Chris Oliver
Alright, pushed updates for that too. Any token expiring within 30 minutes will be considered "expired" and will be renewed.
Ugurcan Kaya
tested and all good  👍 
Notifications
You’re not receiving notifications from this thread.