Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I will build an iOS application whose functionality will be based on access permissions provided by a Django REST application.

Django manages the permissions for the activities in the iOS app. User A can do Work A if he/she is permitted. Permissions will be queried via ASIHTTPRequest to a REST API served by Django Tastypie.

There is no registration. Users will just be able to login via Twitter. XAuth will be used to present a login screen for users.

There are 2 types of users. For example purposes, there will be Type 1 and Type 2. Type 1 will be ordinary user who can only browse data in the iOS app.

Type 2 user can submit/edit data.

That's it theoretically. However...I don't know where to start!!

The biggest roadblock:

How can I hook Twitter XAuth with Django's user backend via Tastypie?

If I know this then I can query the necessary permissions.

Thanks in advance!

like image 376
yretuta Avatar asked Sep 29 '11 02:09

yretuta


1 Answers

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.

like image 74
jawache Avatar answered Nov 07 '22 15:11

jawache