django user auth + gwt - django

I have a django server app that communicates with a gwt front-end using JSON. I want to introduce user authentication to the app and have started to incorporate the framework provided by django. At this point I have set up the server to respond with the user authentication form when necessary (using the #login_required decorator scheme described in the above link), but I'm not sure what to do with this in GWT.
If you are using GWT with django and have implemented user auth, it would be great to hear how you set things up.
Thanks.

The autotest project used gwt and django combination. Have a look at http://autotest.kernel.org/browser/trunk/frontend source code. To be specific I would modify http://autotest.kernel.org/browser/trunk/frontend/afe/json_rpc/serviceHandler.py and add something like below (which would filter login, logout and is__logged__in and for all other functions it would invoke request.user.is_authenticated() to make sure that all other json rpc are protected)
def invokeServiceEndpoint(self, meth, request, response, args):
if meth.func_name == "login" or meth.func_name == "logout" or meth.func_name == "is_loggedin":
return meth(request, *args)
else:
if request.user.is_authenticated():
return meth(request.user, *args)
else:
from studio.rpc_exceptions import AccessDeniedException
raise AccessDeniedException()

I never used Django, but you probably can set what will be returned when login is required.
You can, for instance, return a message so the client can prompt the user with the authentication form. Of course, you would need to account for this situation in every call, but then you could create a abstract request class to do this.

Related

django rest_framework with basic auth, how to consume api with django

I created an API with basic authentication and I was wondering how can i consume it with an username and password
this is my endpoint
http://127.0.0.1:8000/Clerk/
I try to consume it by
def display_clerk_view(request):
displaytable = requests.get('http://127.0.0.1:8000/Clerk/')
jsonobj = displaytable.json()
return render(request, 'clearance/clerk_view.html', {"ClerkClearanceItems": jsonobj})
this block of code and it's giving me error Unauthorized: /Clerk/
I'm planning to use django all-auth with google as provider but for now I want to know how consuming api with authentication works
this is the tutorial i'm following https://www.geeksforgeeks.org/basic-authentication-django-rest-framework/?tab=article
in this case, you are requesting to "/Clerk/" but it's returning unauthorized.
There are two ways to fix this issue:
Remove authentication permission from your view (if function-based view, remove the decorator login_required or is_authenticated condition from the view. If class-based view, add "permission_classes = [AllowAny, ]")
You'r given link: There are used a decorator called "permission_classes", You can replace "#permission_classes([IsAuthenticated])" with "#permission_classes([AllowAny])
If you want authorized action, you can just create a token by username and password.
There are many ways to create tokens, the most popular one is simple-jwt.To learn more follow the link: Simple JWT DOCS

How to implement admin login and logout using Django REST framework?

I have been given a task to authenticate admin login programmatically and logout as well.
I am able to to do login but on logged out when I check which user I am logging out it says AnonymousUser. How can I make sure I log out current user which is logged it.
I am using Django REST framework and testing it on Postman.
#api_view(["POST"])
def adminLogin(request):
if(request.method=="POST"):
username = request.data["username"]
password = request.data["password"]
authenticated_user = authenticate(request,username=username, password=password)
if authenticated_user != None:
if(authenticated_user.is_authenticated and authenticated_user.is_superuser):
login(request,authenticated_user)
return JsonResponse({"Message":"User is Authenticated. "})
else:
return JsonResponse({"message":"User is not authenticated. "})
else:
return JsonResponse({"Message":"Either User is not registered or password does not match"})
#api_view(["POST"])
def adminLogout(request):
print(request.user)
logout(request)
return JsonResponse({"message":"LoggedOut"})
Logging in/logging out with a REST API makes not much sense. The idea of logging in/logging out, at least how Django implements it, is by means of the session, so with a cookie that has the session id.
API clients like Postman usually do not work with cookies: each request is made more or less independent of the previous one. If you thus make the next request without a reference to the session, then the view will not link a user to that request. Clients like AJAX that runs on the browser of course can work with cookies, since these are embedded in the browser that manages cookies. You can work with cookies in postman as specified in this tutorial [learning postman], but this is usually not how an API is supposed to work.
This is why APIs usually work with a token, for example a JWT token. When authenticating, these are given a token that might be valid for a short amount of time, and subsequently it uses that token to make any other request that should be authorized.
As the Django REST framework documentation on TokenAuthentication [drf-doc] says, you can define views that create, and revoke tokens. The page also discusses session authentication that thus can be used for AJAX requests.
But likely you are thus using the wrong means to do proper authentication for your REST API, and you thus might want to work with a token like a JWT token instead.

Django Rest Framework permissions outside Rest Framework view

I am using Rest Framework Token authentication. Which means I cannot know if a user is authenticated outside a rest framework view eg:(A regular django view). The Rest Framework token authentication is a custom auth system which can only be used in a rest framework view.
In a normal rest framework view, I can restrict the endpoint for authenticated users by using this:
class ExampleView(APIView):
permission_classes = [IsAuthenticated]
def get(self, request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
But how will I do that for a regular django view. eg:
def someDjangoView(request):
'''
Note that I cannout use request.user.is_authenticated.
It will always return false as I am using rest framework token authentication.
Which means the request parameter should be of rest framework's and not django's built-in.
'''
content = {"detail": "Only authenticated users should access this"}
return JsonResponse(content)
I am stuck in a situation where I have to know if a user is authenticated (custom auth) outside a rest framework view.
Is there any way to do that?
You can use the api_view decorator to your function-based view to enable DRF:
from rest_framework.decorators import api_view, authentication_classes
#api_view(http_method_names=['GET', 'POST'])
#authentication_classes([YourTokenAuthenticationClass])
def someDjangoView(request):
print(request.user)
...
return JsonResponse(content)
DRF builds on top of the builtin Django contrib.auth user auth system. So, for regular django views, you can use the regular methods provided by contrib.auth.
DRF also supports session-based authentication (usually the default when using contrib.auth). This is ideal, for example, when you have some JavaScript code running in the browser with the user's session.
Note that I cannout use request.user.is_authenticated.
It will always return false as I am using rest framework token authentication
If you are using rest framework token authentication, then you must use views that are compatible with that. request.user.is_authenticated is part of the contrib.auth system built into django. However, you must authenticate a user for this to be True. Rest Framework does this for you. If you're not using the rest framework, you must auth the user yourself!
A simple answer may be to decorate your views to make them utilize the rest framework authentication you define:
#api_view(['GET'])
#authentication_classes(...) # if defaults are not applied
#permission_classes(...) # to apply permissions you need
def view(request):
return Response({"message": "Hello for today! See you tomorrow!"})

how to restrict a view function to be executed from website in django?

i have a website developed using django 1.6.0 with python 2.7.5 . In my view.py file i have a method defined which i want to be executed only when request for that view is redirected request from some where. I want to restrict user from executing that view by typing the url.
suppose view.py:
def online_test(request):
return buy_test_final(request)
urls.py:
url(r'^test$',online_test),
i need to restrict access of online_test method from url.
For making that view accessible for only redirected requests, you can check if request.META has HTTP_REFERER or not.
def online_test(request):
if 'HTTP_REFERER' not in request.META:
raise Http404
return buy_test_final(request)
Edit
As Andrew Gorcester has pointed out, in a comment below, that HTTP headers can be manipulated manually. Not only that, someone can simply add a link on any of your website's page by using Chrome's Developer Tools. Like this: Test. If he clicks this link, request.META will have HTTP_REFERER, thereby executing that view.
Use the above piece of code carefully, if you must.

need an example of doing authorization using django-tastypie

I am relatively new with Django and it's ecosystem. I am writing REST api for our mobile client using django-tastypie. I have gone through almost all the examples on the web about how to use tastypie for creating REST interfaces. but none of them are specific to POSTing the data from client and how would you authorize a client.
I used the from tastypie.authentication.BasicAuthentication as show in the example. It opens a pop up asking username and password and works fine on the browser. But I am not sure, if it will do the same thing on mobile (to be specific, native IOS app). I am not quite getting when a user will make a request to login how this popup will be shown there on his/her mobile device if he or she is not using the browser but the native app.
I am totally lost on this, I would really appreciate your help.
You can check out source and use for example ApiKeyAuthentication.
You just have to POST username and api key to authentificate user.
It looks like usable for ios app.
Here is the part of the checking code.
def is_authenticated(self, request, **kwargs):
"""
Finds the user and checks their API key.
Should return either ``True`` if allowed, ``False`` if not or an
``HttpResponse`` if you need something custom.
"""
from django.contrib.auth.models import User
username = request.GET.get('username') or request.POST.get('username')
api_key = request.GET.get('api_key') or request.POST.get('api_key')
if not username or not api_key:
return self._unauthorized()
try:
user = User.objects.get(username=username)
except (User.DoesNotExist, User.MultipleObjectsReturned):
return self._unauthorized()
request.user = user
return self.get_key(user, api_key)
https://github.com/toastdriven/django-tastypie/blob/master/tastypie/authentication.py#L128
https://github.com/toastdriven/django-tastypie/blob/master/tastypie/authorization.py#L42
Thanks for the help.
I used similar approach mentioned by #Iurii. Here is my solution.
I wrote a class for handling the authentication and override is_authenticated method. and then I can use this class in Meta definition of tastypie resource classes.
from tastypie.authentication import BasicAuthentication
from tastypie.resources import Resource, ModelResource
# class for handling authentication
class MyAuthentication(BasicAuthentication):
def is_authenticated(self, request, **kwargs):
# put here the logic to check username and password from request object
# if the user is authenticated then return True otherwise return False
# tastypie resource class
class MyResource(ModelResource):
class Meta:
authentication = MyAuthentication()
this will ensure a request to access the resource will go through your authentication code.