Jesus / dropbox_api

Ruby client library for Dropbox API v2
MIT License
171 stars 113 forks source link

How do you get the token_hash for refresh tokens? #98

Closed dlynam closed 1 year ago

dlynam commented 1 year ago

I am making one request to authorize a user and would to save the token hash so that I can build an OAuth2::AccessToken at a later time and upload a file without user authorization. I can create the client but if on_token_refreshed is not called, how do I get the token_hash?

For example, I am calling the following once, but on_token_refreshed doesn't get called so I can't get the token hash. Do I need to construct the token_hash manually?

    access_token = authenticator.auth_code.get_token(params[:code], redirect_uri: redirect_uri)
    client = DropboxApi::Client.new(
    access_token: access_token,
    on_token_refreshed: lambda { |new_token_hash|
      # token_hash is a serializable Hash, something like this:
      # {
      #   "uid"=>"440",
      #   "token_type"=>"bearer",
      #   "scope"=>"account_info.read account_info.write...",
      #   "account_id"=>"dbid:AABOLtA1rT6rRK4vajKZ...",
      #   :access_token=>"sl.A5Ez_CBsqJILhDawHlmXSoZEhLZ4nuLFVRs6AJ...",
      #   :refresh_token=>"iMg4Me_oKYUAAAAAAAAAAapQixCgwfXOxuubCuK_...",
      #   :expires_at=>1632948328
      # }
      SomewhereSafe.save(new_token_hash)
    }
  )
tjokerst commented 1 year ago

I ended up building the refresh token when first authorizing the application.

`

  authenticator.auth_code.authorize_url(redirect_uri: redirect_uri, token_access_type: 'offline', grant_type: "authorization_code")

  #redirect here
  auth_bearer = authenticator.auth_code.get_token(params[:code], :redirect_uri => redirect_uri)
  auth_hash =  {
   uid: "#{auth_bearer.params["uid"]}",
   token_type: "#{auth_bearer.params["token_type"]}",
   scope: "#{auth_bearer.params["scope"]}",
   account_id: "#{auth_bearer.params["account_id"]}",
   access_token: "#{auth_bearer.token}",
   refresh_token: "#{auth_bearer.refresh_token}",
   expires_at: auth_bearer.expires_at
 }

`

v2kovac commented 1 year ago

Just do access_token.to_hash to get a copy of that hash immediately. You can just store this the first time you manually do it and grab from this everytime you make a new client. The client will automatically refresh it for you from then on.

You can see how this work here: lib/dropbox_api/endpoints/base.rb#perform_request (only calls your refresh proc on DropboxApi::Errors::ExpiredAccessTokenError)

and

lib/dropbox_api/connection_build.rb#refresh_access_token you can see how it does the refreshing and setting under the hood

dlynam commented 1 year ago

This works, thanks! I didn't realize access_token.to_hash was the same as token_hash in the "Basic set up" section.