breaking into the unknown…

google drive download upload with oauth2 in rails


Now a days many people use to store their document online in their emails, google drive etc. There may be case, when user want to upload some document in proof of, say there loan application or other claims etc from cybercafe, where their local system is not available, so it is good idea to provide this feature in your application if it need user to upload some document. I will explain the implementation here.

STEP 1: Understanding the flow

-> google provide API to access its google drive.

To use google API you need to create a development account with it and get client_id and client_secret . These two will be needed to validate the application trying to connect with the google API. Infact, all API provider whether FB, twitter or any other needs client_id and client_secret  issued by them. More information of google drive API is availabe here .

-> User need to login to there google account to access their google drive

google provides single sign on (SSO) for its API. We will use oauth2 strategy for this. oauth2 gem is available to ease our task.

-> downloading the document of loged in user

We will use google-drive-ruby gem for it. it will manage all upload and download on behalf of the loged in user. The basic implementation is available here . In this post, I will download file from google drive to temp folder of the application. Once, you have the file you can write methods which let the user to download to his system or upload to some other place. But that part I will cover in some other post

STEP 2: Install the required gems

Add below to Gemfile

gem 'google_drive'
gem 'oauth2'

Run bundle install on project root

STEP 3: creating Google API credential

go to and login with your gmail credential. It will ask you to create a project. click the create project button and on the next page which list all the API services, click on drive api button, accept the term and conditions, now you will see that the API button become green and also API access link appear in the side bar. click it, you will see create oauth2 client button, on the next page enter the required detail. See here if you get in problem while creating the credential

I fill below details:

product name : myfinance

Product logo   : select any logo if you have

Home page Url: localhost:3000

Now, click the next button, select web application and click create client id , so Now you have the below detail .

Client ID :
Email address :
Client secret :     UUpzejV2gtYlJe1sFVENYUGN
Redirect URIs :     http://localhost:3000/oauth2callback
JavaScript origins : http://localhost:3000

STEP 4 : creating user authentication with oauth2

oauth2 strategy works with below principal

-> You tell it the SSO url where a user will be authenticated. Here, we are authenticating with google so it will be

-> You need to tell oauth where the authenticated user will be redirected back in your application with the response. In step 2, you have seen that the redirect URI is https://localhost:3000/oauth2callback i,e oauth2 will send back the user to this url, let us write a routes for this url. Add below line to config/routes.rb file

match ‘oauth2callback’ => ‘documents#set_google_drive_token’ # so now we will write our stuff in set_google_drive_token action of documents controller.

Let us first write a library  for user authentication with oauth. Create lib/google_drive folder and create google_docs.rb file in it. It will look like this

module GoogleDrive

  class GoogleDocs

    attr_writer :client_id, :client_secret, :redirect_uri

    def initialize(client_id, client_secret, redirect_uri)
      @client_id = client_id
      @client_secret = client_secret
      @redirect_uri = redirect_uri

    def create_google_client
        @client_id, @client_secret,
        :site => "",
        :token_url => "/o/oauth2/token",
        :authorize_url => "/o/oauth2/auth")

    def set_google_authorize_url
      client = create_google_client
        :redirect_uri => @redirect_uri,
        :access_type => "offline",
        :scope =>
          " " +
          " " +


The create_google_client method instantiate oauth2 class and set_google_authorize_url send the user to gmail for login

STEP 5 : Writing the controller code

create documents_controller.rb file. It will look like this

require 'google_drive/google_docs'
class DocumentsController < ApplicationController
 before_filter :google_drive_login, :only => [:list_google_docs]

 GOOGLE_CLIENT_REDIRECT_URI = "http://localhost:3000/oauth2callback"
  # you better put constant like above in environments file, I have put it just for simplicity
  def list_google_docs
    google_session = GoogleDrive.login_with_oauth(session[:google_token])
    @google_docs = []
    for file in google_session.files
      @google_docs  < < file.title     

  def download_google_docs
    file_name = params[:doc_upload]
    file_path = Rails.root.join('tmp',"doc_#{file_name}")
    google_session = GoogleDrive.login_with_oauth(session[:google_token])
    file = google_session.file_by_title(file_name)
    redirect_to list_google_doc_path

  def set_google_drive_token
    google_doc =,GOOGLE_CLIENT_SECRET,
    oauth_client = google_doc.create_google_client
    auth_token = oauth_client.auth_code.get_token(params[:code], 
                 :redirect_uri => GOOGLE_CLIENT_REDIRECT_URI)
    session[:google_token] = auth_token.token if auth_token
    redirect_to list_google_doc_path

  def google_drive_login
    unless session[:google_token].present?
      google_drive =,GOOGLE_CLIENT_SECRET,
      auth_url = google_drive.set_google_authorize_url
      redirect_to auth_url

We are authorizing the user in the before filter google_drive_login. after authentication it take user to the redirect action set_google_drive_token, here we can retrieve the authentication token from the params[:code] send back with oauth returned url. I have stored that token in session[:google_token], so that I do not need to authenticate the user again. In download_google_docs method we need the name of the file we want to download fron google drive and the path of file where we need to download it.

STEP 6: writing routes for the controller action

Add below routes to config/routes.rb

match 'oauth2callback' => 'documents#set_google_drive_token' # user return to this after login
match 'list_google_doc'  => 'documents#list_google_docs', :as => :list_google_doc #for listing the 
                                                                                  #google docs
match 'download_google_doc'  => 'documents#download_google_docs', :as => :download_google_doc #download

STEP 7: Generating the views

So ,in view list_google_docs.html.erb will list all the docs with a radio buttons(we are downloading one at a time for now) within a form,the form will submit to the download_google_docs action, which after downlaod will be redirected back to the listing page.

<div>Select The document You want to Download</div>
<%= form_tag download_google_doc_path do %>
<% @google_docs.each do |doc|%>
<div><%=radio_button_tag “doc_upload”, doc %> &nbsp;<%=doc%></div>
<%= submit_tag  “Download” %>

That’s all, You can see that, the selected file get downloaded to temp folder


Reference :

Author: arunyadav4u

over 7 years experience in web development with Ruby on Rails.Involved in all stage of development lifecycle : requirement gathering, planing, coding, deployment & Knowledge transfer. I can adept to any situation, mixup very easily with people & can be a great friend.

16 thoughts on “google drive download upload with oauth2 in rails

  1. hey great work!!! I’m working on a project and i’m stuck on uploading files to google drive. could you please post the code for uploading files to google drive in rails? btw…i’m using windows. Thanks

    • Hi Sandy..
      The above code is written, with respect to ruby on rails only.

      Let me know, your problem. I will see, if I can help you out in anyway

      • Hi again. My program is in ruby on rails as well. My problem is with trying to upload a file. I have a webpage with a file upload button. What i am trying to achieve by clicking “Submit” is to have the uploaded file sent directly to the user’s google drive account. Been struggling with it for weeks so any help you can offer will be great. I’m new to the language and this is proving to be quite challenging. By the way i am looking for the server side implementation. Thanks

  2. Hi, this has been a great tut but i’ve been wondering if it’s possible to convine this with omniauth + omniauth-google-apps gems, because I’m building an app where users can login with our company’s email address (a google apps one) and I don’t know if I’m doing it right because users needs to allow access to both login + access drive.

    Anyway, thank you so much for your time to teach the world.

  3. Hi, When my programe process to get_token, I get an error: “faraday::ConnectionFailed: No route to host”. And the program run in rails development mode.

    • can you post , your code here . I can’t tell the problem with the above information .

      • I just follow your step, and start rails project, but when process to get_token, I get the error. And whether my redirect_uri is set to “http://localhost:3000/auth2callback” or “https://localhost:3000/auth2callback” , the code is not function well.
        The code is this: auth_token = oauth_client.auth_code.get_token(params[:code], redirect_uri: ‘http://localhost:3000/oauth2callback’)

  4. Have you defined the routes as explained in step 6 of the blog . I also do not understand why faraday came in picture here. faraday is the gem used to make API calls and I have not used it in the code above.

    Have you made any customization to the above code..???

  5. Yes, I am follow all your steps, and faraday is used in oauth2 gem. So I don’t how it happend!

    • You are right Lee …I missed that faraday is internal dependency of oAuth2. I will try the code on my machine and let you know if Iam able to reproduce your problem.

  6. Hi Lee…

    The above code worked for me (though not related to your error,there do exist some typo error in view and controller code which I corrected) and I’ am able to list and download the documents from Google Drive. You need to replace the client_id and client_secret with your own. Earlier I have put the dummy ID(no one share there real credential in blog : ) ) which may be causing problem. But now I have added the real credential, so copy pasting the code in the blog should also work…Give it a try.

    My current environment in which I have tested the code is as below :

    OS : Ubuntu 12.0
    Ruby: 1.9.3p194
    Rails: 3.2.12

    google_drive (0.3.3)
    oauth2 (0.8.0)
    faraday (0.8.4)

  7. Hi arunyadav4u !
    Thank you for your work, you are very nice! I tested it, I think it function well now. Beause of GWF, I get Operation Time Out. Anyway, very thank you!

  8. Thank you very much!
    I was looking for this.
    Just a couple of things:
    There is a typo on: DocumentsController#download_google_docs

    Be careful copying the view. The double quotes are not the normal ones.

    You should change match for get in the routes.

    • Yes you are right..
      this is some problem with wordpress, it represent the doble quote in some strange way, so if you directly copy paste code from here, make sure to correct the double quote

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s