DRF Can't get data for restricted URLs - django

I'm using simple_JWT and I have a view that requires logged-in users.
When I try to send a request (tested with postman, curl, ...) I get 'Authentication credentials were not provided'.
views.py :
class CurrencyDetailAPIView(generics.RetrieveAPIView):
serializer_class = CurrencyDetailSerializer
lookup_field = "slug"
permission_classes = [IsAuthenticated]
settings.py :
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework_simplejwt.authentication.JWTAuthentication",
],
}

Get a recent token and make sure you are adding Authorization in the header with a value JWT {{your_token}}
Do not skip the space in between.

Related

Django Rest-framework, JWT authentication

I'm newbie in Django Restframework. I use JWT to make login, register API, everythings worked well, I want to GET a user information with authenticated (tokens). This is my code for UserViewSet
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
authentication_classes = [IsAuthenticated,]
I've tested on Postman but i received: "'IsAuthenticated' object has no attributes 'authenticate'"
REST_FRAMEWORK = {
'NONE_FIELD_ERRORS_KEY':'error',
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
}
Could you please to help me to solve this promblem? Thank you very much.
IsAuthenticated is not an authentication class. It's a permission class.
You would put it in permission_classes to allow any authenticated user access to that view set, while authentication (the mechanism of figuring out who the user for that request is) would be handled by that default JWT authentication:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = [IsAuthenticated,]

{ "detail": "CSRF Failed: CSRF token missing or incorrect." }

hello guys . I try to register a new Product in my app using DRF and Postman.
when I send a request I get this error.
the problem is just about my csrf_token.
I'll be thankfull if you help me.....
this is my view
class ProductViewSet(viewsets.ModelViewSet):
authentication_classes = (SessionAuthentication,TokenAuthentication)
permission_classes = [IsAdminUser]
queryset = ProductInfo.objects.all().order_by('-id')
serializer_class = ProductSerializer
filter_backends = (filters.SearchFilter,)
search_fields = ['title','code','owner__username']
I don't have any problem for GET request.
Django requires CSRF token in POST request by default. to avoid CSRF tokens.
Don't use SessionAuthentication as authentication class, coz, it will force you to add CSRF token.
If you still want to use SessionAuthentication then You can use it overrideing
def enforce_csrf(self, request): method
Try below this:
from rest_framework.authentication import SessionAuthentication
class CsrfExemptSessionAuthentication(SessionAuthentication):
def enforce_csrf(self, request):
pass
and use it in your views:
authentication_classes = (CsrfExemptSessionAuthentication ,TokenAuthentication)
If you want to use it globally, you can place it in your REST_FRAMEWORK settings.py file like this:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'myapp.path-to-file.CsrfExemptSessionAuthentication'
],
}
Please make sure you add correct file path in the REST_FRAMEWORK settings
To authenticate with the token.
You must request like this:
curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'
Also make sure you added this in your INSTALLED_APP:
INSTALLED_APPS = [
''''
'rest_framework',
'rest_framework.authtoken',
]
More details can be found here: https://www.django-rest-framework.org/api-guide/authentication/
Because you don't need csrf_token for GET method.
you can set your csrf_token in header like this:
X-CSRFToken: your_csrf_value
so instead of using Cookie add X-CSRFToken to your header in POSTMAN.

How can I bypass drf Token Authentication when using firebase for authentication in django?

I need to sign in a user using firebase from my django app.I have done what I think I needed to do but I seem to be missing something.I am using the pyrebase library.I have created a user on firebase and now I need to sign them in.
I am posting the email and password on Postman and I get the 'idToken' and 'refreshToken', which means the user gets authenticated on firebase.But this only works when I use the drf Token authentication(DEFAULT AUTH CLASSES) and authorization token of a user previously created on django admin. What am I missing so that I can authenticate the user without the drf token authentication?
views.py
config = {
"apiKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
"authDomain": "xxxxx.firebaseapp.com",
"databaseURL": "https://xxxxxxxxx-default-rtdb.firebaseio.com",
"storageBucket": "xxxxxxxxx.appspot.com",
}
firebase = pyrebase.initialize_app(config)
auth = firebase.auth()
class Auth(APIView):
def post(self, request, format=None):
email = "xxxx#gmail.com"
password = "xxxx"
user = auth.sign_in_with_email_and_password(email, password)
return Response(user)
Settings.py
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework.authentication.TokenAuthentication",
),
"DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",),
}
Yeah so basically, you don't need any authorization in any of the authentication views. Since you have a global default of IsAuthenticated, you need to overwrite the permission_classes in the View.
class Auth(APIView):
permission_classes = []
def post(self, request, format=None):
...

Getting "Authentication credentials were not provided." message when trying to access my ModelViewSet URL

I am creating an application using Django Rest Framework and using Token based authentication. I have a PlaceViewSet class inheriting from ModelViewSet. I want both list and retrieve to work even if there is no token sent by the user whereas create, destroy and update should be allowed only if the user has sent the Token. But I am getting Authentication credentials were not provided. for requests of all types. I also want to stick to the REST standard so that the list, retrieve, update, create, destroy comes under the same model view set.
In case if DRF does not allow any requests without Token if I have set my default authentication as TokenAuthentication then why I am able to access the signin and signup views?
You can change permission policy in settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny'
],
}
If you want to add special permissions for methods.
Permission:
from rest_framework.permissions import IsAuthenticated, IsAdminUser
class SpecialPermissionMixin(object):
def get_permissions(self):
user_permission_list = ['list', 'retrieve', 'update']
admin_permission_list = ['destroy', 'create']
if self.action in user_permission_list:
permission_classes = [
IsAuthenticated,
]
elif self.action in admin_permission_list:
permission_classes = [
IsAdminUser,
]
else:
permission_classes = []
return [permission() for permission in permission_classes]
View:
class BlogViewSet(SpecialPermissionMixin, viewsets.ModelViewSet):
...

Django not recognizing my Token?

I'm using Django Rest Framework on the backend and an ember-cli app on the frontend. The authentication is working correctly, but there seems to be a hole somewhere in authorization.
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
}
# views.py
class CurrentUserView(APIView):
"get the data for the current authenticatd user"
permission_classes = (IsAuthenticated,)
def get_queryset(self, request):
queryset = User.objects.filter(username=request.user.username)
return queryset
def get(self, request):
serializer = UserSerializer(request.user)
return Response(serializer.data)
When I make a request to this endpoint /v1/me/ it responds back with a 403. When I take off the permission class, I get back {"id":null,"username":"","is_active":false} because it doesn't know who I am.
Also, when I use the browsable API, the /v1/me URL works correctly.
On the Ember side of things, I login with my account and correctly get back my Token. In the request the Authorization: Token asdf1234asdf1234asdf1234 is being passed. I would think Django takes that token and knows who I am? Am I missing something?
Try something like
from rest_framework import authentication
class TokenAuthView(APIView):
authentication_classes = (authentication.TokenAuthentication,)
Then,
class CurrentUserView(TokenAuthView)
In the setting you need to add auth_token.
# settings.py
INSTALLED_APP = ('rest_framework.authtoken',)
You don't need to add the authentication_classes on every view.