Currently, I am working with a group to try to create a website with a functional Django backend and a React frontend. We are using a user view set
class UserViewset(viewsets.GenericViewSet, mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin):
permissions_classes = (permissions.AllowAny,)
serializer_class = UserSerializer
queryset = User.objects.all()
This is where I am stuck, I haven't used viewsets or serializers before and I am at an impasse on where to go from here. I was hoping to get some clarification of how to add in a create/register user plus login and logout functions so that we can start messing with our api. Any help would be appreciated.
For Login you can use the following code in urls.py-:
from rest_framework.authtoken.views import obtain_auth_token
urlpatterns=[
//your urls
path("api/login/",obtain_auth_token,name="auth_user_login"),]//<-- include this line
]
You can use this endpoint to authenticate using token authentication.
For this you need to do some modification in settings.py file
INSTALLED_APPS=[
//Your existing apps
'rest_framework.authtoken'
]
REST_FRAMEWORK={"DEFAULT_AUTHENTICATION_CLASSES":(
"rest_framework.authentication.TokenAuthentication",
"rest_framework.authentication.SessionAuthentication"
),
}
In react you can send post request to this endpoint with username and password for login. This will send back authentication token which will be used in next requests that needs authentication.
Related
I know what permissions and authentication means. Authentication identifies the user and permissions decide what action can be done by the user. I have implemented a token authentication in django rest framework.
The problem is when i specify both permission_classes and authentication_classes in ListAPIView i cant log in to the account in browsable page.
It only works when i delete authentication classes in the view.
The following view doesn't raise any exception, but gives {
"detail": "Authentication credentials were not provided."
} response. Also not logging in.
class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (permissions.IsAdminUser,)
authentication_classes = [TokenAuthentication]
But after deleting the authentication_classes = [TokenAuthentication] the page works.
PS: curl and httpie works without any problem.
So what could be the issue here? What is the difference between those two classes?
After removing TokenAuthentication class you are able to access the api because then drf is using session authentication and browser handles the sessions for you. When you use TokenAuthentication then you need to add token in header of request which is not done by browser. thats why you are getting { "detail": "Authentication credentials were not provided." }.
try this api from postman by adding the token in headers then it will work.
headers will be like:-
Authorization: Token your-token
check this for token authentication.
https://www.django-rest-framework.org/api-guide/authentication/
and make sure user making the api call should be admin because you have specified IsAdminUser permission.
I am into a weird situation I am login into site and try to submit form if I use permission_classes = [AllowAny] or isAuthenticate classes I get error CSRF Failed: CSRF token missing or incorrect
And in following scenario it gives a popup to enter password and user name . My full class is like
class AddReview(APIView):
serializer_class = ReviewSerializer
authentication_classes = (BasicAuthentication,)
def post(self, request):
rest = request.POST.get('restaurant')
dish = request.POST.get('dish')
And my settings.py is
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
),
}
I just want to submit a post custom form to submit data. Any help or suggestion to make question good would be highly appericiated.
Update
I am able to submit form by using this
class SessionAuthentication(SessionAuthentication):
def enforce_csrf(self, request):
return
But why I have to enforce it ? What I am doing wrong ?
Ideally, you website form should have a csrf token and that should also be sent to server. Maybe something like :
<form method="post">{% csrf_token %}</form>
The CSRF middleware is activated by default in the MIDDLEWARE setting.
If you want to disable CSRF protection just a few views use csrf_exempt() decorator
References
https://docs.djangoproject.com/en/2.2/ref/csrf/#csrf-protection-should-be-disabled-for-just-a-few-views
https://docs.djangoproject.com/en/2.2/ref/csrf/
I'm using django-rest-framework for a simple project. this api doesn't need registration and login for normal users. but it has an admin section on the frontend that can remove or add something to the website(to the database).
Do I need to create a customized ProfileApi App (Login and Authentication App that overrides the default Authentication that django has provided) for having these Possibilities. Or can i send request to /admin url or another url and login and get a token without having trouble of creating another app?
you can use DRF permission class IsAdminUser for these views
class MyAdminView(..):
permission_classes = [IsAdminUser, ]
# rest of view here
I want to add some REST API views to an existing Django project, which uses vanilla Django views. For that I'd like to use the REST Framework. I wonder if I can I mix Django and RF views in a single project and what pitfalls this might have (e.g. with authentication).
Yes you can surely use both of them at the same time, there shouldn't be any issue. Typically the Django views use SessionAuthentication, adn you will use DRF using TokenAuthentication -- best practice is to add both Session and Token authentication to the authentication_classes in the DRF views - that way you can use the browsable api pages to browse the apis once you have signed in via password (session authentication) as well
class GenericViewTest(SuperuserRequiredMixin, View):
def get(self, request, *args, **kwargs):
return HttpResponse("Test")
class PostTrackingCode(CreateAPIView):
"""
"""
authentication_classes = (SessionAuthentication, TokenAuthentication) ----> note this
permission_classes = (permissions.IsAuthenticated,)
serializer_class = TrackingInfoWriteSerializer
model = TrackingInfo
Currently I have a Django project, let's call it Backend. There is a folder api and there I have this resource declared using Django-Tastypie:
from django.contrib.auth.models import User
from tastypie.resources import ModelResource, ALL
from tastypie.authentication import BasicAuthentication
from tastypie.authorization import DjangoAuthorization
from tastypie.cache import SimpleCache
from tastypie.throttle import CacheDBThrottle
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
resource_name = 'user'
excludes = ['email', 'password', 'is_staff', 'is_superuser']
authentication = BasicAuthentication()
authorization = DjangoAuthorization()
cache = SimpleCache()
throttle = CacheDBThrottle()
filtering = {
'username' : ALL,
'date_joined' : ['gt','lt','gte','lte','range']
}
With proper routing rules in place, if I access an URL like http://127.0.0.1:8000/api/v1/user?format=json, I am supposed to get back some info on users in json format, but from my local database. I do not want to use any local database, except maybe for testing with some dummy data. I want such a get request to result in a SOAP request to a certain remote server with my logged in session's username and password.
I already have a standalone Python application, where I can perform a SOAP request and get a SOAP response back using SUDS and pre-downloaded WSDL files. Now I want to include this functionality in my Dhango project in such a way, that I change the settings in settings.py in the project, but I do not have to modify the applications inside the project.
You can define your own Custom managers that use your standalone Python application.
From tastypie documentation. Adding this code to your urls.py should work:
from tastypie.api import Api
from my_app.api.resources import UserResource
v1_api = Api(api_name='v1')
v1_api.register(UserResource())
#old urlpatterns here
urlpatterns += patterns('',
(r'^api/', include(v1_api.urls)),
)