Axel
Axel

Reputation: 467

Use python dropbox API with django

I'm using DropboxOAuth2Flow method described for the dropbox API v1.6 in my Django v1.5.3 application and I'm having a 400 error when redirected to the dropbox oauth2 authorization page.

When I go to to my dropbox_auth_start URL I get redirected to:

https://www.dropbox.com/1/oauth2/authorize?state=tWd4Eh4nzk5NlcuHXe7ffA%3D%3D&redirect_uri=http%3A%2F%2Fmydomain.com%2Fdropbox_auth_finish&response_type=code&client_id=blahblahblah

And then the 400 error occurs.

The "dropbox-auth-csrf-token" is written in the session file by the way.

My django code:

views.py

def get_dropbox_auth_flow(web_app_session):
    redirect_uri = "http://www.mydomain.com"
    return DropboxOAuth2Flow('blahblahblah', 'blehblehbleh', redirect_uri, web_app_session, "dropbox-auth-csrf-token")

# URL handler for /dropbox-auth-start
def dropbox_auth_start(request):
    authorize_url = get_dropbox_auth_flow(request.session).start()
    return HttpResponseRedirect(authorize_url)

# URL handler for /dropbox-auth-finish
def dropbox_auth_finish(request):
    try:
        access_token, user_id, url_state = get_dropbox_auth_flow(request.session).finish(request.GET)
    except DropboxOAuth2Flow.BadRequestException, e:
        http_status(400)
    except DropboxOAuth2Flow.BadStateException, e:
        # Start the auth flow again.
        return HttpResponseRedirect("http://www.mydomain.com/dropbox_auth_start")
    except DropboxOAuth2Flow.CsrfException, e:
        return HttpResponseForbidden()
    except DropboxOAuth2Flow.NotApprovedException, e:
        raise e
    except DropboxOAuth2Flow.ProviderException, e:
        raise e

urls.py

from django.conf.urls import patterns, url, include
from django.contrib import admin
admin.autodiscover()


urlpatterns = patterns('',
    url(r'^dropbox_auth_start/?$',views.dropbox_auth_start),
    url(r'^dropbox_auth_finish/?$',views.dropbox_auth_finish),
)

Upvotes: 3

Views: 2939

Answers (2)

user769283
user769283

Reputation: 21

I've recently had a problem with this and my site link was always using the https link. I'm not sure if my solution is fully valid or secure, but for the moment it stops a bug that's causing a lot of bad signup problems for my service.

Because in some cases the Django Session layer does not seem to work when users are redirected to dropbox and back it seems that the CSRF token is passed back to your app as the "state" parameter in the callback response. My solution is to do a check in your view handler for the authentication that checks if the csrf session key exists and if it does not to get it from the parameter "state" and add it to the session before calling the dropbox request authentication flow.

    try:
        if request.session["dropbox-auth-csrf-token"] is None or request.session["dropbox-auth-csrf-token"] == "":
            raise Exception("Problem with csrf")
    except Exception, e:
        #Get it from the parameter and add it to the session.
        csrf = request.GET.get("state")
        request.session["dropbox-auth-csrf-token"] = csrf

    access_token, user_id, url_state = \
            get_dropbox_auth_flow(request.session).finish(request.GET)

I'm not sure if it's an overall fix that can be added to the Django library for dropbox, to check the request parameter for the state variable if the session is for some reason not working. This may in fact be a security problem, for the moment it solves my signup issues.

Upvotes: 2

Axel
Axel

Reputation: 467

Just like @smarx said, I just switched from HTTP and HTTPS, and everything worked just fine.

Upvotes: 3

Related Questions