If I want to use both TokenAuthentication and SessionAuthentication, I get a CSRF error if it checks the session before the Token. Is this an indicator that something is wrong with my setup, or is this a shortcomming of DRF?
EDIT:
this works, but now everytime someone forgets the token I get an CSRF error.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
}
Related
While working with the rest framework and frontend native client, I need to log in with both native clients and directly to the API endpoint for development and testing purpose.
Native client login requires token authentication and direct API login requires session authentication. But if I put both in settings.py as default I get csrf error from the native client and if I remove session auth I am not able to login directly to API (I can still log in to the admin console).
My settings .py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication'
],
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
)
}
What can be done to log in from both for development and testing? Any help?
#Daniel This is my current setting, check if this helps you -
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
# 'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
)
}
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"
)
when i trying to access api i'm getting this error:
"detail": "Authentication credentials were not provided."
i have included this in settings.py:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':(
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES':(
'rest_framework.permissions.IsAuthenticated',
)
}
my app api urls.py:
from django.urls import path,include
from . import views
from rest_framework import routers
router = routers.SimpleRouter()
router.register(r'',views.UserViewSet, 'user_list')
urlpatterns = router.urls
my views.py:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.object.all()
serializer_class = serializers.UserSerializers
serializers.py:
from rest_framework import serializers
from users.models import User
class UserSerializers(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email','password')
my main urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
path('',include(urls)),
path ('', include(user_urls)),
path('api/',include(api_urls)),
when i running localhost:8000/api i'm getting the error
You can't access the api from the browsers url if you are using TokenAuthentication.
as said by #DarkOrb TokenAuthentication expects a authorization header with token as it's value.
So You must pass token whenever you call the api.
You can test your api using postman.
In above image i have passed token in headers of postman to access my api.
When you call your api from frontend side,pass your token along with the request.
If you just want to use your api in only desktop's browser,in that case you can use SessionAuthentication only.For mobile devices Tokenauthentication must be done.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':(
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
'DEFAULT_PERMISSION_CLASSES':(
'rest_framework.permissions.IsAuthenticated',
)
}
use this in your settings.py file, what is happening is that rest_framework.authentication.TokenAuthentication expects a authorization header with token as it's value, but you can't send that with your browser, to browse API from browser you must have SessionAuthentication enabled.
I'm developing a Django application for Windows with Pyhton 2.7.15. I need to implement an authentication mechanism where if a user has a specific JWT token, he can browse the application (in other words, I just need to verify the token and not generate it). The token is very easy and maybe will be something like this:
Header
{
"alg": "HS256",
"typ": "JWT"
}
Payload
{
"iss": "customIssuer"
}
Signature
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
To implement the verification's service, I installed the Rest framework JWT tools and I modifyed my setting.py in this way:
...
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.TokenAuthentication'
),
}
JWT_AUTH = {
'JWT_ISSUER': 'customIssuer'
}
...
then I modifyed the urls.py:
...
from rest_framework_jwt.views import verify_jwt_token
urlpatterns = [
...
url(r'^api-token-verify/', verify_jwt_token),
...
]
Finally, using Postman, I tryed to send a POST request with the above token but I get a 400 Bad Error error with this body:
{
"non_field_errors": [
"Invalid payload."
]
}
Investigating about the reason I realize that I must add the username claim in the payload but I don't want to. It's possible to configure the application to ignore that claim?
Images in the current database have one piece of data.
But, I am currently experiencing the following error
"GET /images/all/ HTTP/1.1" 401 58"
"detail": "Authentication credentials were not provided."
My Git Hub URL : https://github.com/Nomadcoders-Study/Nomadgram
Which part of the setup went wrong?
I saw your Github project settings.py file.
This error is because you are using IsAuthenticated backend for all of your requests to Rest APIs. Also you setup jwt authorization system:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
),
}
So basically, if you want to create a request to any of your API endpoints, you should provide jwt token authorization header in it. like this for:
curl "<your api endpoint>" -H "Authorization: jwt <token_received>"
Also remember to setup and API to receive token from it, by providing username and password in serializer.
try this in your settings file
settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': ('rest_framework.permissions.IsAuthenticated',),
'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_simplejwt.authentication.JWTAuthentication',),
}
You can add it to your project Settings rest_framework configuration
settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES'('rest_framework.authentication.BasicAuthentication', ),
}
If my webservice (powered by Django Rest Framework, v2.3.8) is inside a location protected by Nginx's HTTP Basic Authentication, like so:
location / {
auth_basic "Restricted access";
auth_basic_user_file /path/to/htpasswd;
uwsgi_pass django;
include /etc/uwsgi/config/uwsgi_params;
}
Then, when a user authenticate and tries to access the API, the following response is obtained for all views:
{"detail": "Invalid username/password"}
Does Django Rest Framework pick up the HTTP Authorization header (meant for Nginx) even though the view requires no authentication? If so, how should I go about this?
Any help would be greatly appreciated.
By default, Django Rest Framework has two authentication classes, see here.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication'
)}
You can disable the rest framework authentication if you don't need it.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ()
}
Or you can remove only BasicAuthentication as it will work in your case.
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication'
)}
As noted in another post, you must add a comma next to the authentication class or it can throw a TypeError.
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.authentication.SessionAuthentication', #comma added here
)
Source: https://stackoverflow.com/a/22697034/5687330