Plug in django-allauth as endpoint in django-rest-framework
Asked Answered
C

5

50

I'm using django-allauth on my website for social logins. I also have a REST API powered by django-rest-framework that serves as the backend of a mobile app. Is there a way I can directly plug in allauth's authentication backend to the REST api so that I can validate (and register) users who use Facebook login in the mobile app?

To clarify: The Facebook login part is handled by native SDKs. I need an endpoint that works like POST /user (that is, creates a new user), but takes Facebook oauth token as input instead of email/password etc.

Collogue answered 25/7, 2013 at 15:8 Comment(1)
possible duplicate of oauth2 token authentication using django-oauth-toolkit and python-social-authAlbanian
C
18

You can use Django Rest Auth for this which depends on django-allauth. It's very easy to integrate.

Coverall answered 4/1, 2018 at 9:3 Comment(3)
This is the ultimate answer! ThanksMental
repository is unmaintained/abandoned from 2 years.Johiah
github.com/iMerica/dj-rest-auth is what is used nowAppressed
V
12

You can use this libray for social authentication django-rest-framework-social-oauth2. Try this django-allauth related code

urls.py

urlpatterns = [
    url(
        r'^rest/facebook-login/$',
        csrf_exempt(RestFacebookLogin.as_view()),
        name='rest-facebook-login'
    ),
]

serializers.py

class EverybodyCanAuthentication(SessionAuthentication):
    def authenticate(self, request):
        return None

views.py

class RestFacebookLogin(APIView):
    """
    Login or register a user based on an authentication token coming
    from Facebook.
    Returns user data including session id.
    """

    # this is a public api!!!
    permission_classes = (AllowAny,)
    authentication_classes = (EverybodyCanAuthentication,)

    def dispatch(self, *args, **kwargs):
        return super(RestFacebookLogin, self).dispatch(*args, **kwargs)

    def get(self, request, *args, **kwargs):
        try:
            original_request = request._request
            auth_token = request.GET.get('auth_token', '')

            # Find the token matching the passed Auth token
            app = SocialApp.objects.get(provider='facebook')
            fb_auth_token = SocialToken(app=app, token=auth_token)

            # check token against facebook
            login = fb_complete_login(original_request, app, fb_auth_token)
            login.token = fb_auth_token
            login.state = SocialLogin.state_from_request(original_request)

            # add or update the user into users table
            complete_social_login(original_request, login)
            # Create or fetch the session id for this user
            token, _ = Token.objects.get_or_create(user=original_request.user)
            # if we get here we've succeeded
            data = {
                'username': original_request.user.username,
                'objectId': original_request.user.pk,
                'firstName': original_request.user.first_name,
                'lastName': original_request.user.last_name,
                'sessionToken': token.key,
                'email': original_request.user.email,
            }
            return Response(
                status=200,
                data=data
            )

        except:
            return Response(status=401, data={
                'detail': 'Bad Access Token',
            })
Vasodilator answered 16/9, 2015 at 11:34 Comment(1)
You could give me a guide on how I can make it work in the same way for the google provider.?? Thanks in advance.Monocotyledon
J
2

While I'm not quite sure how to use allauth and rest-fremework together, allauth does not offer such an endpoint.

Suggestion: make your own that does a variation of the following:
Call allauth.socialaccount.providers.facebook.views.fb_complete_login(None, socialtoken) where socialtoken is as created in login_by_token. That performs (a few functions deeper) a django.contrib.auth.login, possibly creating the acct.

After that, for use on mobile devices, it might be possible to the the auth (not FB) token: get the user data (from session?), and call rest_framework.authtoken.views.obtain_auth_token

Notes:
1. This offers no way to resolve email conflicts or connect social/local accts.
2. I haven't tried it - please post code if you can get it working.

Johannesburg answered 5/9, 2013 at 6:39 Comment(0)
S
2

Because this is still the top answer when searching for Django Allauth support for DRF, I'll add that API support was recently merged into main on Allauth itself, so now you shouldn't need any third parties to achieve this. Here are the docs for anyone interested.

Sitdown answered 8/5 at 10:50 Comment(0)
M
1

You could use djoser but I don't know how it cooperates with allauth: https://github.com/sunscrapers/djoser

Mystery answered 17/4, 2015 at 12:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.