[Fixed]-Making Twitter, Tastypie, Django, XAuth and iOS work to Build Django-based Access Permissions

1👍

I’ve done something similar with django + tastypie and facebook login for iOS.

Authentication

  1. Log the user in using whatever means you will, get the access_token.

  2. Create a GET request tastypie endpoint to which you will pass the accesstoken as a query string.

  3. On the server side validate etc… and then create your own internal “tastypie” token and return that in the response to the get request e.g:

class GetToken(ModelResource):
    """
    Authenticates the user via facebook and returns an APIToken for them.
    """

class Meta(object):
    queryset = ApiKey.objects.all()
    resource_name = 'authenticate'
    fields = ['user', 'key']
    allowed_methods = ['get']
    authorization = Authorization()
    authentication = FacebookAuthentication()

def prepend_urls(self):
    """We override this to change default behavior
    for the API when using GET to actually "create" a resource,
    in this case a new session/token."""

    return [
        url(r"^(?P<resource_name>%s)%s$" % (self._meta.resource_name, trailing_slash()),
            self.wrap_view('_create_token'), name="api_get_token"),
        ]

def _create_token(self, request, **kwargs):
    """Validate using FacebookAuthentication, and create Api Token if authenticated"""
    self.method_check(request, allowed=['get'])
    # This checks that the user is authenticated on facebook and also creates the user
    # if they have not been created.
    self.is_authenticated(request)
    self.throttle_check(request)

    bundle = self.build_bundle(obj=None, request=request)
    bundle = self.obj_create(bundle, request, **kwargs)
    bundle = self.full_dehydrate(bundle)

    self.log_throttled_access(request)
    return self.create_response(request, bundle.data)


def obj_create(self, bundle, request=None, **kwargs):
    """Create a new token for the session"""
    bundle.obj, created = ApiKey.objects.get_or_create(user=request.user)
    return bundle

  1. Pass the returned API key on all subsequent calls, can either be as a query string param again or I set it on the Authorisation header for every call.

  2. Make sure ALL the other resources you want to have authentication on have ApiKeyAuthentication() set in the Meta.

class ThingResource(ModelResource):
    class Meta:
        queryset = Thing.objects.all()
        resource_name = 'thing'
        authentication = ApiKeyAuthentication()

Authorisation

So now you know on the server side that the user is who they say they are, what is this user allowed to do? Thats what the authorisation meta is all about.

You probably want Django Authorisation in which case you can just use the normal permissioning schemes for users, or you could roll your own. It's pretty simple.

0👍

amrox has a nice example on how to hook a custom fork of django-oauth-plus that supports xAuth into tastypie. I imagine it can be tweaked to suit your purposes.

Leave a comment