Michael Bates
Michael Bates

Reputation: 1934

django-ouath-toolkit with social-auth

I'm trying to setup social-auth (python-social-auth) to talk to another Django project with django-oauth-toolkit.

I want Django project A to login using OAuth2 from Django project B. Django project A uses social-auth and project B uses django-oauth-toolkit as the OAuth2 provider.

Project A can successfully login to other OAuth2 providers such as Google, but I get the following error when trying to login using my custom made backend:

AuthStateMissing at /sso/complete/custom-backend/
Session value state missing.

This is how the custom backend has been implemented in Project A:

class CustomBackend(BaseOAuth2):
    name = 'custom-backend'
    EXTRA_DATA = [
        ('profile', 'org')
    ]

    def authorization_url(self):
        return "%s/oauth2/authorize" % self.setting("URL")

    def access_token_url(self):
        return "%s/oauth2/token" % self.setting("URL")

    def user_data(self, access_token, *args, **kwargs):
        resp = requests.get("%s/me/" % self.setting("URL"), headers={
            'Authorization': "Bearer %s" % access_token
        })
        if resp.status_code != 200:
            raise Exception("Error while getting user details from auth source.")
        data = resp.json()

        return {
            'username': data['email'],
            'first_name': data['first_name'],
            'last_name': data['last_name'],
            'user_id': data['id'],
            'email': data['email']
        }

There is a setting called SOCIAL_AUTH_CUSTOM_BACKEND_URL which is equal to the base URL of project B (http://localhost:8001 for testing).

The URL when Project B redirects to Project A (when the error is raised) is: http://localhost:8000/sso/complete/custom-backend/?redirect_state=6kg4S1eitCMqTTzFGrm9uerG37UNkUPl&code=e64by72AkD2unMVVsGZCz0V2byuUyu&state=6kg4S1eitCMqTTzFGrm9uerG37UNkUPl

Thoughts would be appreciated, thanks.

Upvotes: 0

Views: 577

Answers (1)

Michael Bates
Michael Bates

Reputation: 1934

As I discovered, HTTP cookies are not separated by ports on the same host. So I had project A (the OAuth2 client) running on localhost:8000 and project B (the OAuth2 server) running on localhost:8001. Django's sessionid Cookie was getting overridden during the auth process, which caused this error.

The solution is to run the OAuth2 server on a different host (I just made an entry in /private/etc/hosts on macOS that looks like:

127.0.0.1    id.localhost

and updated SOCIAL_AUTH_CUSTOM_BACKEND_URL to http://id.localhost:8001.

Upvotes: 1

Related Questions