We're using rest_framework.authentication.TokenAuthentication to authenticate API users in Django REST Framework using an access token.
Is there a way to use this same class to authenticate users for Django generally?
I've tried adding it straight in to AUTHENTICATION_BACKENDS but it doesn't work:
AUTHENTICATION_BACKENDS = (
# Needed to login by username in Django admin, regardless of `allauth`
"django.contrib.auth.backends.ModelBackend",
# `allauth` specific authentication methods, such as login by e-mail
"allauth.account.auth_backends.AuthenticationBackend",
'rest_framework.authentication.TokenAuthentication',
)
Is there a quick way to do this or do I need to write a custom authentication backend?
Django REST framework authentication and permission classes require the use of Django REST framework views, as the authentication is done on the view level [1]. This is different from Django authentication backends, where the authentication is done through the middleware.
Is there a way to use this same class to authenticate users for Django generally?
No, Django REST framework authentication backends are distinctly separate from Django authentication backends, and the reverse is technically true [2].
[1]: There has been discussion of moving this to the middleware level, but this is not currently planned.
[2]: Django authentication backends can be used through SessionAuthentication and other comparable DRF backends.
You can use SessionAuthentication.
AUTHENTICATION_BACKENDS = (
# Use Django's session framework for authentication.
'rest_framework.authentication.SessionAuthentication',
....
'rest_framework.authentication.TokenAuthentication',
)
Related
I have a Django Rest Framework (DRF) application and when we are using the browseable API page and click login it goes to the default Django login page. I want to override it to another page.
Default api:
https://my-app/api-auth/login/
But the new login page I want is this:
http://my-app/signin/
the auth is done by Okta in the application.
I did try overriding this
LOGIN_REDIRECT_URL = '/signin/' LOGIN_URL = '/signin/'
from rest_framework import authentication
class CustomAuthentication(authentication.BasicAuthentication):
def authenticate(self, request):
# perform custom authentication logic here
# ...
# return a tuple of (user, auth) or None if authentication fails
return None
Then you will need to add this authentication class to the DEFAULT_AUTHENTICATION_CLASSES in the REST_FRAMEWORK setting in your settings.py file
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'path.to.CustomAuthentication',
]
}
I am using Django 1.11 and Django rest framework 3.6.2
I created a custom authentication backend:
MyAuthBackend(rest_framework.authentication.BasicAuthentication):
# ...
and added it to the settings.py file:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES' : ('path.to.MyAuthBackend',)
}
I also tried to extend SessionAuthentication without success
My issue is that users are trying to log in via the browsable api and it looks like the authentication backend that the browsable api is using is not the default one.
Where can I change that? I have to use my own auth backend in the browsable api,
Thank you.
I don't think it's possible to use BasicAuthentication in the browseable api (without changing a whole bunch of its internals).
Consider keeping the SessionAuthentication alongside your new one, you can use basic authentication in your app and session authentication in the browsable api:
'DEFAULT_AUTHENTICATION_CLASSES': (
'path.to.MyAuthBackend',
'rest_framework.authentication.SessionAuthentication',
),
Currently I've extended the standard Django user class by linking it to a profile class. The profile model is partially used for account activation through email, and includes an account_activated boolean. I'd like to require that accounts be activated in order to login in any way, including using the login button that is added to the django rest framework browsable api by adding
url(r'^api-auth/', include('rest_framework.urls',
namespace='rest_framework')),
from the tutorial here http://www.django-rest-framework.org/tutorial/4-authentication-and-permissions/
to the project urls. Is there any way to do this?
I think this is a classical example where permissions work fine. What you need to do:
Create a permission class that will check for a user if her account
is activated. For more see drf documentation;
Add your new permission class to the set of default permissions in settings.py in drf settings:
settings.py
REST_FRAMEWORK = {
...,
'DEFAULT_PERMISSION_CLASSES': [
...,
'your.permission.class',
...,
],
...
}
I want to build a server side base for analytics using Python/Django. The script should catch requested urls and update the database before routing the url requested using urls.py. How can this be done??
To do such things you should use middleware. Copying from the documentation:
Middleware is a framework of hooks into Django’s request/response processing. It’s a light, low-level “plugin” system for globally altering Django’s input or output.
A middleware is a simple class that can define a number of methods. You'd need to define the process_request or process_view method and there do your database updates etc
Try using a middleware:
class MyTrackingMiddleware(object):
def process_request(self, request):
# save your request path here
return None
And add it MIDDLEWARE_CLASSES in settings.py
I have used django-social-auth in my project to enable the user to sign in using different social websites like twitter or facebook. For that I have to enable different authentication backends in settings.py like this:
AUTHENTICATION_BACKENDS = (
'social_auth.backends.twitter.TwitterBackend',
'social_auth.backends.facebook.FacebookBackend',
)
By enabling these backends I can not login to django admin page. Where an occurs saying that username of password not correct for a staff user.
I have disabled these backends then admin page is working but I am not able to achieve the functionality of sign in using different social websites. Please help me out in this problem. All the suggestions will be appreciated.
Add django.contrib.auth.backends.ModelBackend to this list:
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'social_auth.backends.twitter.TwitterBackend',
'social_auth.backends.facebook.FacebookBackend',
)
when no AUTHENTICATION_BACKENDS is specified, backends list defaults to sole ModelBackend