5

I am working on script to get google contacts using google contacts api gem. I am able to access the token successfully using this code:

require 'rubygems'
require 'launchy'
require 'oauth2'
require 'googlecontacts'
require 'google_contacts_api'

# Get your credentials from the console
CLIENT_ID = 'your Id'
CLIENT_SECRET = 'your Secret'
OAUTH_SCOPE = 'https://www.google.com/m8/feeds'
REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob'

client = OAuth2::Client.new(CLIENT_ID, CLIENT_SECRET,site: 'https://accounts.google.com',token_url: '/o/oauth2/token', authorize_url: '/o/oauth2/auth')
url = client.auth_code.authorize_url(scope: OAUTH_SCOPE, redirect_uri: REDIRECT_URI)
Launchy.open(url)
$stdout.write  "Enter authorization code: "
code = gets.chomp
token = client.auth_code.get_token(code, :redirect_uri => REDIRECT_URI)

PROBLEM:

I know that this is not the best way to do it, because it is tiring. every time I run the script the user has give access instructions. And also I have to manually copy paste the token from the browser to the terminal.

QUESTION:

How can be able to store the retrieved token, and when it expired how can I refresh it?

ben
  • 6,000
  • 5
  • 35
  • 42

3 Answers3

8

It looks like you're using the oauth2 library to get the access token. The AccessToken class has to_hash() and from_hash() methods, which you can use to serialize and deserialize the token once you've gotten it, as well as a refresh() method to refresh the access token once it's expired. If this is a command line script you can use a hidden file in the user's home directory to store the serialized token.

Eric Koleda
  • 12,420
  • 1
  • 33
  • 51
  • what I am not understanding is: "what can I add in the above code so as to return an hash with the access token and also the refresh token?". thats the problem. I mean something like this: { "access_token":"1/fFAGRNJru1FTz70BzhT3Zg", "expires_in":3920, "token_type":"Bearer", "refresh_token":"1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" } – ben Oct 23 '14 at 21:59
  • 1
    When you run `client.auth_code.get_token` method, the response will be a `AccessToken` object. And as you can see in the [source code](https://github.com/intridea/oauth2/blob/master/lib/oauth2/access_token.rb), this class has all the info you want, like `token`, `refresh_token`, expire info, and a method to refresh the auth. – Rael Gugelmin Cunha Oct 23 '14 at 23:24
  • I got a way. Thanks Rael & Eric for your answer. I am now able to access the refresh token. I am going to find a way to use it for exchange of a new token once it expires. – ben Oct 24 '14 at 20:59
  • from the above code: the access token will be token.token. Refresh token: token.refresh_token. Expires at: token.expires_at. And so on... – ben Oct 25 '14 at 10:07
3

During the first authentication, you got an authorization token and a refresh token.

Store the refresh_token (in session if it's a web app, or any other "volatile" persistence scheme, or in last case in database).

Using the refresh_token, ask for a new token like described in Google OAuth2 WebServer documentation.

If this is not a webserver application, maybe you should consider use other OAuth2 authentication flows.

Rael Gugelmin Cunha
  • 3,327
  • 30
  • 25
  • exactly it is not a webserver application. Under google developers application console, I have used the application type as INSTALLED APPLICATION. ..I have seen authentication using OAUTH2 flows like here https://github.com/google/google-api-ruby-client-samples/blob/master/drive/drive.rb. I can implement this, but the only problem is how I can get that specific access token. maybe you can help me on how to get that token only. thanks for the ans. – ben Oct 23 '14 at 15:53
  • Right, so the Google doc for installed applications is located [here](https://developers.google.com/accounts/docs/OAuth2InstalledApp). Anyway, your user will face a browser window asking grants. And again, you'll receive 2 tokens, one for authorization, and other for refresh. As all requests are only HTTP requests, maybe you can use the rest-client gem to follow the documentation. May I ask you your goal? Maybe import contacts? – Rael Gugelmin Cunha Oct 23 '14 at 19:30
  • yes, to import all the email addresses. any ideas which can make me do it better? And also I tried following the google doc and it is opening the window where I should copy paste the token to the terminal.I had one problem: how to automatically get the token as they are suggesting in the documentation. – ben Oct 23 '14 at 22:07
  • Well, I work at Cloudsponge, a service to import contacts for several sources (Gmail, Yahoo, AOL, Linkedin, Facebook, etc), and it's free to test. You can see our HTML widget on the [Test-Drive page](http://www.cloudsponge.com/test-drive) or you can use our [API for several languages](http://cloudsponge.com/contact-importers/gmail). If you want partial solutions, you can use [omniauth gem](https://github.com/intridea/omniauth). – Rael Gugelmin Cunha Oct 23 '14 at 22:56
1

In order to receive a refresh token, you need to alter the url.

in OAuth2:

url = client.auth_code.authorize_url(scope: OAUTH_SCOPE, access_type: "offline", redirect_uri: REDIRECT_URI)

Then it will be available like Erik Koleda mentions.

Ivo Dancet
  • 191
  • 2
  • 5