Saturday morning usually I start with chess but now I decided play with some code. It really hurts when you start some software development and try use such beast like Google API – huge amount of information, huge amount of working examples with different bunch of code or just breadcrumbs… It’s not so easy start developing when you don’t understand principles : OAuth, OAuth2, token, refresh token, client secret, client id, redirect uri, offline, online, scopes …. Why at least I need OAuth2 where is my lovely “basic authentication” with username and password ?
Ok let’s clarify things one by one :
- Task to be accomplished – what we want to achieve this nice morning and what is our goal and how we can proceed.
- Authentication – let’s get a passport for flight through the wire
- Specifics – or how we can create google spreadsheet
- Documentation – good articles and source code examples I found so far
Task to be accomplished :
To be clever guy I decided learn google API and add data to google spreadsheet and use that data for any purpose later. To have things more complicated let’s play with other users’ data. For such reason we need create an application in Google developers portal
In developers console you need create a project and press magic button : “Enable an API”
Do you remember why I called Google as a monster 🙂 ? Look at that huge APIs’ list : Maps, Books, Youtube, Blogger, Drive, Google+ …. Find your own.
In which area we decided create an app ? Yes, we agreed work with Drive API – spreadsheets. So we will ask for full, permissive scope to access all of a user’s files.
Authentication :
The Google API also supports older authorization options, such as OAuth 1.0, AuthSub, or ClientLogin; however, in most cases I recommend migrating to OAuth 2.0 if possible. If your application has certain unusual authorization requirements, such as logging in at the same time as requesting data access (hybrid) or domain-wide delegation of authority (2LO), then you cannot currently use OAuth 2.0 tokens. In such cases, you must instead use OAuth 1.0 tokens.
The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf
Next step is obtain OAuth 2.0 credentials from the Google Developers Console.
In APIs & auth section press menu item “Credentials” and “Create new Client ID” button. In the next screen choose : “web application” and change domain if you have it. If you don’t have a domain yet, please follow this blog post and “create” your own binding with fake domain (For Linux platform users : play with ifconfig I guess)
Ok, as a result we have Client ID, Client Secret, redirect uri. Those are main parameters for authentication.
Let’s be secure and use OAuth 2.0. You may ask about OAuth 2, how it works ? Better read this article which explains this process thoroughly
The image above has been stolen from article I just mentioned. Forgive me dear Google. We have 3 calls right ? On first step we have intermediate window called “Consent Screen”. This screen allows to the end user decide for : use our app or not use, share resources or not to share. The end user will be informed and he must agree in case he wants continue work with our application further. Remember about “redirect uri” you entered in Google. This is entry of second step and it is for exchanging access token. And last step is about getting data. I insist play with google authplayground to clarify those steps first. Of course if you are pissed off abstractions you can go and build those 1 mile length urls directly into browser. It’s also fine for me 🙂 Starting from authplayground can save you a lot of time and you can be sure about your scope and access rights…
N.B. : First time response gives you (in 2 step) an access token and refresh token, following responses return access token only. So you need store refresh token either in memory or in database. Struggled ? Play with authplayground 😉
Ok I’m clear about how it works. Let’s write some code. I’m a .NET developer. First thought came into my mind was nuget. So let’s say we have MVC application already. Let’s install some google libs :
if I’m working with Microsoft ASP.NET MVC I’m predicting that I’m not one in the planet. Should be something regarding MVC right ?
Here you go :
I’m pretty sure I have everything I need to have connection with Google.
First thing I want to do is connect to the end user’s drive and create new spreadsheet. Google.Apis libraries have a flow (have those 3 steps in mind). It means you call your ASP .NET MVC action. Before accessing any resource of Google you do authentication first. In “Consent screen” user gives us access rights to his google drive. And we can work with files.
In google controller we will have action called InsertNewSpredsheet.
AuthorizationCodeMvcApp and AppFlowMetadata is some automation, abstractions you will find in Google.Apis libraries
In AppFlowMetadata you must provide your client Id, secret, scopes and storage of access tokens. See example below :
From code I just provided you can see that I’m using File2DataStore. It’s overridden by me. Standard FileDataStore I changed to my own needs. Standard FileDataStore stores auth keys in “C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Drive.Api.Auth.Store”
I don’t think so that you will allow IIS_IUSRS users access this location in production environment 🙂 Think twice, don’t do that. Rewrite FileDataSource to your own needs. Here is two examples how you can do it :
https://code.google.com/p/google-api-dotnet-client/source/browse/Src/GoogleApis.DotNet4/Apis/Util/Store/FileDataStore.cs
http://www.daimto.com/google-oauth2-csharp/#FileDataStore
So we have some automation here – flow. When you define redirect uri in google developers console you need refer this url to controller action defined below. So in such case you need add redirect url as :
http://yourproject.com/AuthCallback/IndexAsync
Specifics
Next step is go back to our action InsertNewSpredsheet and write code which is responsible for file creation :
We just created excel spreadsheet file into google drive. Here is the list of other mimeTypes for google :
application/vnd.google-apps.audio
application/vnd.google-apps.document
application/vnd.google-apps.drawing
application/vnd.google-apps.file
application/vnd.google-apps.folder
application/vnd.google-apps.form
application/vnd.google-apps.fusiontable
application/vnd.google-apps.kix
application/vnd.google-apps.photo
application/vnd.google-apps.presentation
application/vnd.google-apps.script
application/vnd.google-apps.sites
application/vnd.google-apps.spreadsheet
application/vnd.google-apps.unknown
application/vnd.google-apps.video
To work with google spreadsheet we need add more libs from nuget – Google.GData.Client and Google.Gdata.Spreadsheets :
using Google.GData.Client;
using Google.GData.Spreadsheets;
Following code is for creating query factory for spreadsheetservice. Each request will have all credentials we need :
One moment. Because it’s not real production example I copied refresh token and added it directly.
Last step is create header row and add first contact. I spent some time with error : Bad Request (400) … In google documentation https://developers.google.com/google-apps/spreadsheets/#adding_a_list_row I didn’t find any information regarding this issue. It seems that you cannot insert just rows. First you need have header row. Cell names of header row should be lowercase and exactly match with your code. So you can either add header row manually or do it using your code like I did.
That’s it. 2 controllers. One for automate flow, another ours with functionality. I hope this article will save you some time 😉 Cheers
Documentation
https://developers.google.com/ – Start
https://developers.google.com/oauthplayground/ – want to play and understand OAuth2
http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server You can play with OWIN for google authentication
https://developers.google.com/google-apps/spreadsheets/ work with google spreadsheets
https://github.com/googledrive/dredit working example in python, ruby, .net, java, android languages