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
Related
I am implementing a web application using Django framework.
In my business I need to let the users have access to the app only by google login.
I also don't need to register the users in my database, it isn't a requirement. I just need that the user will uses his google account to enter the site so I will be able to get his real email to send him back the result of the session. It is a one shot app.
I am using django-allauth but it exposes by default a way to login and register users locally. Is it a way to disable every kind of local registration/login and let the user enter in the app only by google login?
Thank you.
From https://django-allauth.readthedocs.io/en/latest/advanced.html#creating-and-populating-user-instances you'll need to:
disable signup on a custom ACCOUNT_ADAPTER
enable signup only through social account (google) on a custom SOCIALACCOUNT_ADAPTER
In practice:
# settings.py
ACCOUNT_ADAPTER = 'myapp.adapters.AccountAdapter'
SOCIALACCOUNT_ADAPTER = 'myapp.adapters.SocialAccountAdapter'
# myapp/adapters.py
from allauth.account.adapter import DefaultAccountAdapter
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
class AccountAdapter(DefaultAccountAdapter):
def is_open_for_signup(self, request):
return False
class SocialAccountAdapter(DefaultSocialAccountAdapter):
def is_open_for_signup(self, request, sociallogin):
return bool(sociallogin)
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.
So, i am currently working on a web application project and i implemented authentication and password confirmation successfully.
But my issue is that i did it using html templates and now the requirement came up that we have to develop our application using api's for the backened.
Now, i am new to api and really confused how to use the authentication system i built (as we have to provide template to the in-built implemented class and they accept the values from their itself)
Is it possible to actually see and manage the registered users from the code-behind while still using there in-built mechanism
For password change you can use this generic view using the inbuilt Django auth framework
#login_required
def change_password(request):
if request.method == "POST":
form = PasswordChangeForm(request.user, request.POST)
if form.is_valid():
user = form.save()
# Important to update the session otherwise user will have to login again
update_session_auth_hash(request, user)
# Server side alert
print("Password changed for {0}".format(user.username))
return redirect('/index/')
else:
print(form.errors)
else:
form = PasswordChangeForm(request.user)
return render(request, 'website/changepassword.html', {'form': form})
You need to use djangorestframework, and use the decorator #apiview(['GET', 'POST']) to create a RestAPI
You can use TokenAuthentication available in django rest framework. See what documentation says:
TokenAuthentication
This authentication scheme uses a simple token-based HTTP Authentication scheme. Token authentication is appropriate for client-server setups, such as native desktop and mobile clients.
To use the TokenAuthentication scheme you'll need to configure the authentication classes to include TokenAuthentication, and additionally include rest_framework.authtoken in your INSTALLED_APPS setting:
INSTALLED_APPS = (
...
'rest_framework.authtoken'
)
Note: Make sure to run manage.py migrate after changing your settings. The rest_framework.authtoken app provides Django database migrations.
You'll also need to create tokens for your users.
from rest_framework.authtoken.models import Token
token = Token.objects.create(user=...)
print token.key
For clients to authenticate, the token key should be included in the Authorization HTTP header. The key should be prefixed by the string literal "Token", with whitespace separating the two strings. For example:
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
Note: If you want to use a different keyword in the header, such as Bearer, simply subclass TokenAuthentication and set the keyword class variable.
If successfully authenticated, TokenAuthentication provides the following credentials.
request.user will be a Django User instance.
request.auth will be a rest_framework.authtoken.models.Token instance.
Unauthenticated responses that are denied permission will result in an HTTP 401 Unauthorized response with an appropriate WWW-Authenticate header. For example:
WWW-Authenticate: Token
The curl command line tool may be useful for testing token authenticated APIs. For example:
curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'
Note: If you use TokenAuthentication in production you must ensure that your API is only available over https.
Source: http://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication
I am using Allauth to login with twitter in my Django app.
I have a problem to logout from existing account to login with different one.
I make logout in function logout in my views.py
and within it i tried to call:
from django.contrib import auth
auth.logout(request)
but it didn't work.
I also tried to expire session using this:
request.session.set_expiry(1)
to expire the session after 1 second, but it also didn't work.
By the way I use my own signup and login (I just save mail and password)
So Any ideas?
All auth takes care of it, jut build a url to:
/accounts/logout/
No need to write your own view. If you want to know what it does you could override their view.
I have a single page angularjs application utilizing JWT authentication. Because JWTs are sent with every single request, it seems redundant to use CSRF tokens in my forms. In order to disable CSRF checking, I commented out 'django.middleware.csrf.CsrfViewMiddleware' in my settings.py middleware classes. This all works fine.
However, when I use the Django Admin panel, CSRF is used. This seems reasonable since JWTs don't protect the Admin pages.
When I log into Admin, a cookie is set containing the CSRF token. When I try to POST to REST endpoints from my angularjs app while logged into an Admin session, the requests contain the CSRF cookie, and the Django REST backend rejects the POST with a 403 status. If I delete the cookie from my browser settings and re-POST, it goes through as expected.
I can configure my app not to set CSRF cookies, but how do I configure my app to ignore the CSRF cookie if it was set by another app on the same domain? I can't guarantee that a token won't be set by something else as I don't control all of the apps that will be running on the domain.
I am using class-based views that extend viewsets in the Django REST Framework. I attempted to address this by decorating my classes with csrf_exempt, but this did not seem to work (still get 403 response). Could I be doing it wrong, or is there some other solution that I am missing?
Here is my attempt at csrf_exempt:
class AccountList(generics.ListCreateAPIView):
serializer_class = serializers.AccountSerializer
def get_queryset(self):
return models.Account.objects.all()
#method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(AccountList, self).dispatch(*args, **kwargs)
It sounds like you have SessionAuthentication enabled, which is the part of Django REST Framework that enforces CSRF for cookie-based authentication. Since you are using JWT, and you mentioned that all pages use JWT for authentication, you should be able to just remove SessionAuthentication from your list of default authentication classes.
If you actually need it, you can just move it to the bottom of the default classes. Because it is detecting the authentication cookies, and authentication was successful, SessionAuthentication will fail before JWT is checked.