Dropbox REST API Part 6: OAuth Callback

March 17, 2012

IntroductionDropBox Logo

With this entry into the Dropbox series we come back to the beginning of the cycle. We started with authentication and that’s where we’ll end.

Having a user authorize your application to access his or hers Dropbox account consists out of 3 steps. Using OAuth you must:

  1. Retrieve a request token
  2. Have the user authorize your application
  3. Retrieve an access token

Before retrieving an access token you must wait until the user has authorized your application. There’s no way to determine when this has happened. Up until now we just waited a little while and hoped for the best. However, when you instruct the user to authorize your application, you can also specify a callback URL which will automatically be called when the authorization process has been completed.

Let’s create a sample web application that demonstrates this.

Table Of Contents

MVC 3 Template

Download the code of part #5 (article #67), unzip it and open it up in Visual Studio. Add a new MVC 3 web application called “MvcApplication” to the solution.

Add New Project

Make sure to select the Internet Application template so that we don’t have to create a basic layout ourselves.

Project Template

The first thing I did was to remove the about page and everything related to the account pages (login, register…etc.). You won’t need them. I just want to get a simple one page site up and running as fast as possible. After removing these unnessary pages, user controls, markup…etc. You should wind up with a site resembling the following:

MVC Web Application

Feel free to adjust the default messages on the page as you please.

Top of page

Authorization

Let’s kick off the authorization process. Add a reference to the OAuthProtocol and Dropbox.Api projects. Next add a simple form to the home page (Index.cshtml).

@using (Html.BeginForm("AuthorizeDropbox", "Home"))
{
    <input type="submit" value="Gimme access to your Dropbox account" />
}

Which results in this cutting edge form:

Web Form

When you submit the form the AuthorizeDropbox() action is executed. Let’s implement it.

First add your application’s key and secret to the HomeController class.

private const string ConsumerKey = "your application key";
private const string ConsumerSecret = "your application secret";

Then add the following action to the controller.

public ActionResult AuthorizeDropbox()
{            
    var oauth = new OAuth();
    var requestToken = oauth.GetRequestToken(
        new Uri(DropboxRestApi.BaseUri), ConsumerKey, ConsumerSecret);

    Session["requestToken"] = requestToken;

    var action = Url.Action("Authorized", "Home", null, Request.Url.Scheme);
    var callbackUri = new Uri(action);            

    var authorizeUri = oauth.GetAuthorizeUri(
        new Uri(DropboxRestApi.AuthorizeBaseUri), requestToken, callbackUri);

    return Redirect(authorizeUri.ToString());
}

First you retrieve a request token and temporarily store it in the session state. Next you compose the callback URL which is automatically called after the user has authorized your application. The callback should resemble something like this:

http://localhost:53291/Home/Authorized

Last, but not least you retrieve the authorization URL and redirect the user to it so he can start the authorization process. The user will now be redirected to his Dropbox account where he’ll have to login and get a chance to authorize your application.

Top of page

OAuth

If you compile now you should get some compiler errors. You’ll need to modify the OAuth type located in the OAuthProtocol project slightly. Open OAuth.cs code file and add an extra parameter (callbackUrl) to GetAuthorizeUri(…) method.

public Uri GetAuthorizeUri(Uri baseUri, OAuthToken requestToken, Uri callbackUrl)
{
    //...
}

Now you need to modify the implementation of this method. It’s really simple actually. If a callback URL is specified, just append it to the query string.

var queryString = String.Format("oauth_token={0}", 
    requestToken.Token);
if (callbackUrl != null)
{
    queryString = String.Format("{0}&&oauth_callback={1}", 
        queryString, callbackUrl);
}
var authorizeUri = String.Format("{0}{1}?{2}", baseUri, 
    "oauth/authorize", queryString);
return new Uri(authorizeUri);

And for good measure let’s add an overload, so that the existing code (which is not expecting this extra parameter) doesn’t break.

public Uri GetAuthorizeUri(Uri baseUri, OAuthToken requestToken)
{
    return GetAuthorizeUri(baseUri, requestToken, null);
}

Top of page

Callback

If you specified a callback URL then the user will be redirected here once he has authorized your application. Dropbox will provide a couple of values via GET parameters in the URL:

  • oauth_token: The request token that was just authorized.
  • uid: The user’s unique Dropbox ID.

Let’s add an action to the home controller so that we can handle the callback.

public ActionResult Authorized(string oauth_token, string uid)
{
   //...
}

The implementation is straight forward.

var requestToken = (OAuthToken) Session["requestToken"];

var oauth = new OAuth();
            
var accessToken = oauth.GetAccessToken(
    new Uri(DropboxRestApi.BaseUri), ConsumerKey, ConsumerSecret, requestToken);

ViewBag.UserId = uid;
ViewBag.AccessToken = accessToken;

return View();

First you need to retrieve the request token / secret from the session state. Then you can retrieve an access token. You need to store this access token somewhere, so that you can use it next time instead of forcing the user to follow the entire authorization process again.

To finish this sample I just display a simple view which lists the access token. But ofcourse, what you do once you’ve got access to the user’s Dropbox account is up to you.

You can download the source code accompanying this article from the download page. If you have any questions or suggestions please drop me an e-mail or submit a comment.

Top of page

Advertisements

18 Responses to “Dropbox REST API Part 6: OAuth Callback”


  1. […] Dropbox REST API Part 6: OAuth Callback (Christophe Geers) […]

  2. MrZer0 Says:

    First of all your tutorial is absolutely brilliant! It’s a clear step by step guide on how to use the Dropbox API with .NET.

    In my opinion this should be added to the list of third party SDKs on Dropbox.net!
    Even it’s not a finished SDK it describes a great way how to build your own and for anybody who has some problems with DropNet & Co (like me) it’s an fantastic alternative.

    At last I’ve one question to part 6:

    While using a localhost address (on ASP.NET Developer Server) I get not redirected to my page. But trying e.g. google.com works well.
    Is there any restriction for localhost/127.0.0.1 with callback parameter?

    PS: Sorry for my bad English

    • MrZer0 Says:

      Ok, now it’s working fine.
      It wasn’t a problem with localhost instead I made a redirection to the calling page and end up with an loop.

    • Christophe Says:

      Glad you like the series. Your English is fine btw.

      IIRC I tested it myself with a localhost address and with an external site. Worked fine in both cases.

      Try your external IP address instead. Normally your browser should do the redirect if a HTTP 3xx response is sent back to the client.

      Perhaps Dropbox handles the redirect in another way, but since it worked fine with me I don’t think so.

      Maybe put the question on the Dropbox forums?

  3. provector Says:

    Hi

    Thanks for this great series of .net dropbox.

    Made my life a lot easier 🙂

    Best regards.

    Jimmy

  4. stefanjagger Says:

    Hi
    Great write up, thank you… although not quite a novice article, but I’m not complaining.
    I had a bit of issues running this on VS2010 Premium with SP1, had to download MVC 3 from Microsoft.
    For some reason the app bugs out with a 403 forbidden error unless I put a wait in OAuth.cs before:
    var response = request.GetResponse();
    I presume this is the App running through instead of waiting for response.
    I’d be lost how to fix it but thought i’d give you heads up in case something is broke.
    Too much coding for me… have to learn the basics first…
    Thanks
    Stefan

  5. cap Says:

    What do you think about a method to serialize the AcessToken into xml?


  6. Hey i want to synchronize the files with a time interval of 5 mins what should be done ? like i wanna sync my sql database from my c# app with dropbox at interval of 5 mins

  7. Lupita Says:

    Christophe:
    Is it possible to register an app and get the app key and app secret given a user account information (user email and password)?
    I’m trying to do an application to work with any dropbox account, and I don’t expect users to register my app manually.
    How do I do this registration on any dropbox account?

  8. Lupita Says:

    Nevermind, I just read how oauth works, sorry.

  9. Tooba Says:

    Thanks for the awesome tutorial! I have a question though, how do I determine if the user actually clicked Allow and not Deny? Even if i click Deny, the user is redirected to the callback url…

  10. gulfamwani Says:

    Hi Christophe,
    I want to implement OAuth Callback in the Dropbox REST API to upload my files in my respective dropbox account using dropbox API’s,So what i want is that all the authentication should happen via console only.
    I should not go to open the browser and authenticate the user,it should take login credentials via console only.
    I hope you would had understood my requirement,let me tell you once more.

    1 when i am running my script(Controller_App.py) i am getting the URL

    e.g url: https://www.dropbox.com/1/oauth/authorize?oauth_token=c4x39zv899kjqos
    Please visit this website and press the ‘Allow’ button, then hit ‘Enter’ here.

    2 After coping this URl to browser it redirects me to the dropbox sign in page were i need to give my login credentials.

    3 After successful login i need to press Allow button to allow it to connect with App

    4 Then coming back to console i need to hit enter and after words i am able to upload the files.

    Here i am attaching my code files,please let me know were exactly i need to do the changes so that all the authentication should happen via console.i.e during
    the execution of my script (controller_App.py)

    Waiting for your response..

  11. Bojan Says:

    Many thanks Christophe. You have made out life much easier with this series. Keep up the great work!

  12. artcava Says:

    Hi Christophe, thank’s a lot for your step by step tutorial. Great one!

    I’m searching for a way to use Dropbox API silently, without “allow” passage… I mean that the user allow the first time and then application remember this choice, is that possible in your opinion?


    • You need to authorize the app at least once to obtain an access token for that user.

      A temporary workaround for this is to run it once, grab the user’s access token and secret (by printing it), then storing it in variables or a .config file and accessing it appropriately (using Christophe’s code, save create a new OAuthToken and pass it in when creating the DropboxApi).

      This access token doesn’t expire for some time so you can keep it in your variables/config file.

  13. Cristovao Oliveira Says:

    Hi Christophe, Great tutorial!

    I also want to authenticate the user only once. Store the user access token and then use it when needed.

    Here is my question:

    I am trying to use dropbox REST Api OAuth 2.0. There are some differences of version 1 that you are using on the tutorial. I am able to authenticate without no issues, but i am not able to upload files with access token with OAuh 2.0. I would like to understand better the differences between token received from version 1.0:
    http://myurlredirect.com/?oauth_token=HKA4ev2wEieXl7LS&uid=123456

    and version 2.0:

    https://myurlredirect.com/#access_token=2UiwhnPPKYEAAAAAAAAAELsJ4M3EZAyY11a4IvKFvzdcKQU-728zsas_474AzXaU&token_type=bearer&uid=123456

    I do not find any c# example using OAuth 2.0 and upload files.

    Tanks in advance.


Comments are closed.

%d bloggers like this: