I am developing a django server as a backend to an iOS app. Until now, I've been creating new users through a registration page through the browser. I would love though to be able to register new users through a form in my iOS app. I am using Django REST, for the mobile API to my django server.
Unfortunately, to be able to POST any requests, I need authorization. This is perfectly fine, as the vast majority of the time, my users need to be logged in. The only time they are using my app when not logged in, is exactly when they're signing up (new user).
Signing up means creating a new user. Creating a new user, means inserting new data to the database, which of course according to RESTful practices, means I need to use a POST request. But how do I do that without authorization, since I'm not logged in yet.
I have two ideas on how to potentially do it, below, but I would love to know what the best practice is.
1) When new user goes to the sign up view, the django server can silently create a new user account, with default initial data. This new account can be sent as data to the app, allowing authorization to be formalized. The registration view, simply updates the user account. I would probably need to delete this new user, if it isn't updated (registration form was not sent in due time).
2) Have a hardcoded "admin" user, that is simply used to authorize these anonymous POST requests. I imagine it is possible to limit this admins scope to only one function?
Django REST framework allows you to set the permission policy on a per-view basis. You can use this to allow unauthenticated POST requests on just the registration view. For example, if you use an APIView
for this:
from rest_framework.permissions import AllowAny
from rest_framework.views import APIView
class RegistrationView(APIView):
permission_classes = (AllowAny,)
...
You can still keep IsAuthenticated
as the default permission for all other views.
For more information, read "setting the permission policy"
I'd try something like extend the Authentication class you are using (let's say it is BasicAuthentication
) and customize the is_authenticated
method to fit your scenario, this is a rough example.
class AnonymousPostAuthentication(BasicAuthentication):
""" No auth on post / for user creation """
def is_authenticated(self, request, **kwargs):
""" If PATH and POST match your scenario,
don't check auth, otherwise fall back to parent """
if request.path == "/<path_to_your_anonymous_post_service>" \
and request.method == "POST" :
return True
else:
return (super(AnonymousPostAuthentication,self)
.is_authenticated(request, **kwargs))
Of course, you need to change your Authentication backend later to something like:
AUTHENTICATION_BACKENDS = [
'project.path.to.AnonymousPostAuthentication',
]
You can extend this in the official docs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With