Django Rest Framework - For user registration getting authentication error - python

I am registering the user by using this post , In this case successfully i am creating the user.
After above step, I enabled token authentication by using this post, but the main problem is when i perform registration operation it is showing "detail": "Authentication credentials were not provided." this error.
Here i don't need authentication checking for user registration, need authentication checking for remaining apis.
Can anyone please help me out how to disable authentication for user registration.
Thanks in advance

Depending on how you want your endpoint to be accessed and the level of publicity you can use 1 of 2 permissions.
Either AllowAny or IsAuthenticatedOrReadOnly
AllowAny will allow for anyone accessing each of the methods you've defined for the viewset.
IsAuthenticatedOrReadOnly will, by default, allow anyone to use the safe http methods GET, HEAD or OPTIONS on your endpoint but in order to POST, PUT/PATCH or DELETE you would need to be authenticated.
You add these to each of your endpoints for fine grained control
from rest_framework import permissions
class MyViewSet(viewsets.GenericViewSet):
permissions_classes = (permissions.AllowAny, )

Related

django rest auth facebook code for login

On project I use django-rest-auth for user registration and authentication. Also i added code for facebook login:
from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter
from rest_auth.registration.views import SocialLoginView
class FacebookOAuth2AdapterFixed(FacebookOAuth2Adapter):
def __init__(self):
pass
class FacebookLogin(SocialLoginView):
adapter_class = FacebookOAuth2Adapter
And in my project urls.py I add
url(r'^rest-auth/facebook/$', FacebookLogin.as_view(), name='fb_login'),
But on url localhost:8000/rest-auth/facebook I see form with 2 parameters: Access token(already have) and code.
My question is next: Can I login via facebook without this code, and if not, how can I get this code without frontend? How can I check work user authentication/registration or not?
PS: SocialApp created, facebook app created, app id and app secret added to social app.
Only one of "Access Token" or "Code" field is required. (I have not tested the Code field but the Access Token field works, with the Code field left blank)
To use Access Token, after the user performs the "Login to Facebook" step on the client side using Facebook javascript SDK, you will receive a response from Facebook which includes "accessToken" for accessing data on Facebook. Simply paste this accessToken into the "Access Token" field and it will automatically login and/or create the user's account from data retrieved from Facebook.
Obviously you can then perform the same process by posting the access token to the form all in javascript.
In the field of Access Token, Pass the User Access Token that you will get from Facebook developer dashboard(generate and debug), code field you can leave as blank. It will create user in your application and will return JWT token with user details.

Create Django token-based Authentication [duplicate]

I am trying to figure out the best way to implement token based authentication in my django app. An external, non-django application is setting a cookie, with a token, and I have a webservice that can retrieve user information based off of that token. If the user has the cookie set, they should not need to authenticate on my site and should be automatically logged in based on the info passed back by the web service. As I see it, there are a few different options to perform the actual check and I'm not sure which is best:
Write a custom decorator like the one in this snippet and use it instead of
login_required.
Call a custom authenticate method inside base_site through an ajax call. On every page, a check would be made and if the cookie exists and is valid, then the user would be automatically logged in.
Add some javascript to the LOGIN_REDIRECT_URL page that will check/validate the cookie in an ajax call, and automatically redirect back to the referrer if the cookie authenticated.
Is there an option I am missing? Ideally, there would be a way to build this into login_required, without having to write a custom decorator.
Before searching for code, be sure you read the documentation. http://docs.djangoproject.com/en/1.2/topics/auth/#other-authentication-sources
Also read the supplied Django source.
You want to create three things.
Middleware to capture the token. This is where most of the work happens. It checks for the token, authenticates it (by confirming it with the identity manager) and then logs in the user.
Authentication backend to find Users. This is a stub. All it does is create users as needed. Your identity manager has the details. You're just caching the current version of the user on Django's local DB.
Here's the middleware (edited).
from django.contrib.auth import authenticate, login
class CookieMiddleware( object ):
"""Authentication Middleware for OpenAM using a cookie with a token.
Backend will get user.
"""
def process_request(self, request):
if not hasattr(request, 'user'):
raise ImproperlyConfigured()
if "thecookiename" not in request.COOKIES:
return
token= request.COOKIES["thecookiename"]
# REST request to OpenAM server for user attributes.
token, attribute, role = identity_manager.get_attributes( token )
user = authenticate(remote_user=attribute['uid'][0])
request.user = user
login(request, user)
The identity_manager.get_attributes is a separate class we wrote to validate the token and get details on the user from the IM source. This, of course, has to be mocked for testing purposes.
Here's a backend (edited)
class Backend( RemoteUserBackend ):
def authenticate(**credentials):
"""We could authenticate the token by checking with OpenAM
Server. We don't do that here, instead we trust the middleware to do it.
"""
try:
user= User.objects.get(username=credentials['remote_user'])
except User.DoesNotExist:
user= User.objects.create(username=credentials['remote_user'] )
# Here is a good place to map roles to Django Group instances or other features.
return user
This does not materially change the decorators for authentication or authorization.
To make sure of this, we actually refresh the User and Group information from our
identity manager.
Note that the middleware runs for every single request. Sometimes, it's okay to pass the token to the backed authenticate method. If the token exists in the local user DB, the request can proceed without contacting the identity manager.
We, however, have complex rules and timeouts in the identity manager, so we have to examine every token to be sure it's valid. Once the middleware is sure the token is valid, we can then allow the backend to do any additional processing.
This isn't our live code (it's a little too complex to make a good example.)

How to use Django's #csrf_exempt decorator to enable an API to do PUT?

I'm building a Django application with Django-Rest-Framework APIs. I have built an API endpoint as shown below.
I want to be able to POST data from my browser. I want this POST operation to retrieve an object model from my Database that has the matching primary key as given in the URL. And I want to modify that retrieved object based on the data posted by the browser.
If I could just grab the posted data from with my ViewSet, I would be done. But when I try to execute that viewset's update() function, I get a CSRF error.
From my urls.py file:
router.register(r'replyComment', views.ReplyComment, base_name="replyComment")
From my views.py file:
class ReplyComment(viewsets.ViewSet):
def update(self,request,pk=None):
try:
origComment = Comment.objects.get(pk=pk)
# Do something here that modifies the state of origComment and saves it.
return Response(
json.dumps(True),
status=status.HTTP_200_OK,
)
except Exception as exception:
logger.error(exception)
return Response(status=status.HTTP_400_BAD_REQUEST)
I'm using the Advanced Rest Client (ARC) tool in my Chrome browser. When I point the ARC tool to http://127.0.0.1:3001/api/replyComment/2/ using the POST method, I get the following error:
{
detail: "CSRF Failed: CSRF token missing or incorrect".
}
This doc indicates that I should use the #csrf_exempt decorator. I put that decorator on my update() function above. But it seemed to make no difference.
What changes do I need to make to ensure my POST works as I intend it to?
It is highly recommended NOT to disable CSRF protection for session authentication. Doing so will make your app vulnerable to attacks. For the API, DRF enforces CSRF protection only for session authentication. If you use another authentication backend(Basic, Auth Token or OAuth) it will work with out asking for CSRF tokens since CSRF attacks happen only in browsers. Now if your API is going to be used by non-browser clients, you can enable one of the other auth backends. For example, Using Basic auth:
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.BasicAuthentication',
),
And enable basic auth in ARC.

Subclassing User to differentiate between an admin and an App with an API key?

This is my first API, so please forgive/correct me if I make any wrong claims.
I have an app that has an API. I would only like external apps (mobile clients etc.) with a valid API key to have access to it, and I think django-rest-framework's TokenAuthentication is the right fit for it. I would also like users to be able to log in with their username & password, and I'm looking to use OAuth2Authentication for that. But I don't want apps that use TokenAuthentication to have a "User" instance in the database (as they are not users in the traditional sense) so I'm thinking about doing something like this:
class Client(User):
pass
django-rest-framework says that request.user will be an instance of User. Will I bump into any problems if I use Client instead?
Is this the standard way of handling this situation? It just doesn't feel right to me (mainly because of question 1)
For mobile clients to have access to your API, using django-restframework's TokenAuthentication will work just fine. As you have already ascertained. You need to design a mechanism for handing out your tokens. If you are doing this dynamically then you will need to have your API request handle this.
Mobile Client: ( initial API request )
request /API/rabbit/1/
( no token)
Server: 401
test for the token ( fails )
'login please' via HTTP 401 response. ( or some other custom header or response information )
You can define your api on how to accomplish this, most folks use the http:
401 Unauthorized error code. I point this out because its clearly a design decision.
Mobile Client: ( request login)
prompts user for username and password, and makes a request too /login/ this could be a special mobileclient login like /mobile/login/ whose difference is that it hands back a token on a successful login.
Server: 200
verifies valid user and hands out token.
you could write this logic, or you could use 'rest_framework.authtoken.views.obtain_auth_token' which I recommend. See rest-frameworks
token authentication for details on this. Heed its warning about https.
Mobile Client: ( re-request API with token in http header)
receives token
now remakes initial request to /API/rabbit/1/ with its token in the header.
Server: 200
verifies valid token in the header and provides access to API. You will be writing this code.
Finally: You will need to design a strategy to 'age-out' your tokens, and or lock out users.
Also: make sure you add 'rest_framework.authtoken' to your INSTALLED_APPS, and make sure you call manage.py syncdb
Aside: you do not specifically have to use the TokenAuthentication ( request.user, request.auth) you can write your own code to peek in the header and see if the token is set. This is fairly easy to do with the python Cookie lib. You are still using-heavly the token management features of django-rest-framework. To be honest I think there documentation is a bit incomplete on configuring the 'TokenAuthentication' authentication back-ends.
Hope this helps!

Django request.user is empty

Using django, I am authenticating the user through Google. I get the initial request tokens & redirect the user to google for auth. After which google redirects the user back to my website (using the redirect_url I provide).
At this point the request.user.id is None so is request.user.username why is this happening? I need the user ID to enter the access_tokens (that google sends me) into the DB.
Under what conditions can request.user object in Django be empty?
UPDATE1: When I get redirected back from Google with the url pattern as http://mywebsite.com/lserv?s=goog control comes back to my django views function, but django gives me the request.user object user as Anonymous user with no username or id. why?
UPDATE2:
all this is running on python manage.py runserver for now...
UPDATE3: Anybody faced anythn similar to this? basically, out of no reason the user in request clears out automatically & I get assigned as Anonymous user. All this happens between url requests from the user (from browser). Why?
Django's auth mechanism has nothing to do with Google's or any other auth service. If you want to integrate third party auth service with your Django site, you should do it youself.
If you're using oauth2 library, it's README has a section named "Logging into Django w/ Twitter" may help you.
If you are using oauth api from google. To get the user you have to do something like this
from google.appengine.api import oauth
# ...
try:
# Get the db.User that represents the user on whose behalf the
# consumer is making this request.
user = oauth.get_current_user()
except oauth.OAuthRequestError, e:
# The request was not a valid OAuth request.
# ...

Categories

Resources