Hi I'm trying to customize
jwt graphql Django default authentication
I need to achieve log in with username or email
normal Django we customized authentication backend.
mutation{
tokenAuth(username:"myemail#email.com"
password:"pass")
{
token
}
}
Authenticate with username
mutation{
tokenAuth(username:"myname"
password:"pass")
{
token
}
}
the normal username is working fine.
how I can authenticate the user by username or email in jwt graphql
I tried this link
https://django-graphql-jwt.domake.io/en/latest/customizing.html
I don't get any idea about that...
Does anyone have any idea about that??
You have to make the changes on the Model level not in JWT, JWT will follow, because JWT is only a presentation of what is going on behind the scenes.
Look at the link under here, maybe it will help you! :)
Multiple USERNAME_FIELD in django user model
Disclaimer - mama's answer should work. Halfway through writting an answer I realised I'm wrong, but I still wanna show you what I wanted to suggest. It shows what JWT TokenAuth mutation does and a way to tap into that completely.
change the inbuild Django authentication like mama's answer suggests
rewrite graphql_jwt.decorators.token_auth to look at both fields, not just one
write your own class for the TokenMutation that uses this decorator on it's mutate function
Something like so (untested):
def two_field_token_auth(f):
#wraps(f)
#setup_jwt_cookie
#csrf_rotation
#refresh_expiration
def wrapper(cls, root, info, password, **kwargs):
context = info.context
context._jwt_token_auth = True
username = kwargs.get('username')
email = kwargs.get('email')
user = your_auth_method(
request=context,
username=username,
email=email,
password=password,
)
if user is None:
raise exceptions.JSONWebTokenError(
_('Please enter valid credentials'),
)
if hasattr(context, 'user'):
context.user = user
result = f(cls, root, info, **kwargs)
signals.token_issued.send(sender=cls, request=context, user=user)
return maybe_thenable((context, user, result), on_token_auth_resolve)
return wrapper
class TwoFieldJWTMutation(JSONWebTokenMutation):
#classmethod
#two_field_token_auth
def mutate(cls, root, info, **kwargs):
return cls.resolve(root, info, **kwargs)
All the necessary imports you can find here and here
Related
I want to write a decorator like the login_required decorator of Django to check the Azure AD authentication and the Django authentication at the same time. If one of the two is not true, it redirects to the login page.
For the authentication, I used the tutorial (https://learn.microsoft.com/en-us/graph/tutorials/python). I do not how to deal with groups and permissions since I use Azure AD authentication. So I take the username and surname from the token that comes from the Azure Authentication and with this two infos, I create an user in the User Django models. I know it is not the best idea, but I can start to play with groups and permissions.
The django authentication is automatic without that the user create it. It is done in the callback function.
def callback(request):
# Make the token request
result = get_token_from_code(request)
#Get the user's profile
user = get_user(result['access_token'])
# Store user
store_user(request, user)
# Get user info
# user attribute like displayName,surname,mail etc. are defined by the
# institute incase you are using single-tenant. You can get these
# attribute by exploring Microsoft graph-explorer.
username = user['displayName']
password = user['surname']
email = user['mail']
try:
# if use already exist
user = User.objects.get(username=username)
except User.DoesNotExist:
# if user does not exist then create a new user
user = User.objects.create_user(username,email,password)
user.save()
user = authenticate(username=username,password=password)
if user is not None:
login(request,user)
messages.success(request,"Success: You were successfully logged in.")
return redirect('home')
return redirect('home')
If I want to check if the user is authenticated by Azure AD. From the tutorial, I should do something like that :
if request.session.get('user').get('is_authenticated') :
But I do not know how to combine with the django authentication to check both. Anyone can help me
Thanks
simplest way would be to use the user_passes_test decorator to make your own function and apply that as a decorator to your views as per the docs
from django.contrib.auth.decorators import user_passes_test
def check_azure(user):
# so something here to check the azure login which should result in True/False
return #theResult of your check
#user_passes_test(check_azure)
def my_view(request):
...
Here is my solution :
from django.shortcuts import redirect
def authenticated_user(view_func) :
def wrapper_func(request, *args, **kwargs):
if request.user.is_authenticated and request.session.get('user').get('is_authenticated') :
return view_func(request, *args, **kwargs)
else :
return redirect('login')
return wrapper_func
I am new to django and writing authentication system for my application. Right now I have built the basic login/logout functionality.
What I want is that whenever a logged in user wants to access their profile page, they should be asked to confirm their password.
I have searched this on django docs but I was not able to find any resource on how to achieve. I know flask has a fresh_login_required decorator which does this, just wondering if it is possible to do the same thing with django as well.
I don't think there is any function for this in django. But you can write on your own with help of django session. For example:
First, we need to write a decorator:
# decorator
def require_fresh_login(function):
#wraps(function)
def wrap(request, *args, **kwargs):
has_verified_profile = request.session.pop('has_login_verified',None)
if has_verified_profile:
return function(request, *args, **kwargs)
else:
return redirect(reverse('fresh_password_view_url'))
return wrap
Then there should be a view for fresh_password_view_url, where you need to put a value against key has_login_verified in request.session. For example:
def verify_fresh_password(request):
form = SomeForm(request.POST)
if form.is_valid():
password = form.cleaned_data.get('password')
if request.user.check_password(password):
request.session['has_login_verified'] = True
return redirect('profile_view')
# else send error response
I have been learning how to use djangorestframework token authentication using different blog posts and youtube videos.
As for reference, I was following the blog here: https://chrisbartos.com/articles/how-to-implement-token-authentication-with-django-rest-framework/
I could not understand how are we going to check the token before accessing any page. I mean, I am developing an app, that exposes the todos a user creates through the rest framework. I have added a login that saves a user and returns the token created for that person. Now,I want to check that token to find the todos api that the person created and view it in my browser in a seperate url.
As an example:
Once I login through localhost:8000/api/v1/login,
I should get the todos created by me at api/v1/todos in json rest api format.
And if I go to api/v1/todos/1/, it should give me the details of the todo, as I have created in the serializers.
I would like to add some more info:
So, say I have created a class for the login form. It will create a token for me.
So the following is the login in the views:
def signin(request):
username = password = ''
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
return HttpResponse('Logged In')
else:
return HttpResponse('Wrong credentials')
return render(request,'login.html')
So, I want to create a token for this. As mentioned in the djangorestframework documentation https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication
it creates a seperate view for accessing the api-auth-token that is obtained from the function obtain_auth_token. But, how do I apply this function to save the token from current login in a class based view.
Also, how do I pass this in another class based view, such that it shows no authentication in case I have not logged in but gives me the api in json when authenticated?
https://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication
Add rest_framework.authentication.TokenAuthentication to the DEFAULT_AUTHENTICATION_CLASSES in the REST_FRAMEWORK options in your Django settings.py file.
Add rest_framework.authtoken to your INSTALLED_APPS in settings.py
You can use the #authentication_classes decorator before the views you want to protect like so:
#authentication_classes((TokenAuthentication,))
def sample_function(request):
You'll also need to create tokens for your users, which is documented in that initial link.
class loginview(APIView):
permission_classes = [
permissions.AllowAny # Anyone can Login
]
def post(self,request):
email_address = request.data.get('email')
user_request = get_object_or_404(
User,
email=email_address,
)
username = user_request.username
password = request.data.get("password")
user = authenticate(username=username, password=password)
id_u = user.id
if not user:
return Response({"error": "Login failed"},
status=status.HTTP_401_UNAUTHORIZED)
token, _ = Token.objects.get_or_create(user=user)
return Response({"token": token.key,'id':id_u})
Here is some sample code you can use to obtain Token while using the Login API From the App Frontend. Auth Token can be accessed from the Token model. Don't forget to add:
from rest_framework.authtoken.models import Token
Also Add rest_framework.authtoken to installed apps in the settings.py
I have successfully setup django-allauth along with a custom user model which let's users sign in directly using email and password or through Facebook, in which case email is taken from Facebook and saved in the Email field of the custom user model. I have also created a mobile field which stays empty as of now.
I want to allow users to log in using their Facebook, Email or MOBILE. Unfortunately that field is not unique=True in the model. I have thought of capturing the mobile and fetching the associated email address and then use that along with the password to log in any user.
However, I don't know how to extend the SIGN IN form that comes with django-allauth or the block of code that signs a user in where I can change it to meet my need.
As of now I don't find any of my current code relevant to this problem, but if it helps I am willing to provide it upon mention.
The following solution worked for me. I put the code in the forms.py file.
from allauth.account.forms import LoginForm
from auth_project import settings
class CustomLoginForm(LoginForm):
def __init__(self, *args, **kwargs):
super(LoginForm, self).__init__(*args, **kwargs)
if settings.ACCOUNT_AUTHENTICATION_METHOD == "email":
login_widget = forms.TextInput(attrs={'type': 'text',
'placeholder':
('Mobile Number'),
'autofocus': 'autofocus'})
login_field = forms.CharField(label=("Mobile"),
widget=login_widget)
self.fields["login"] = login_field
set_form_field_order(self, ["login", "password", "remember"])
def user_credentials(self):
credentials = {}
mobile = self.cleaned_data["login"]
login = CustomUser.objects.filter(mobile=mobile).values('email')[0]['email']
if settings.ACCOUNT_AUTHENTICATION_METHOD == "email":
credentials["email"] = login
credentials["password"] = self.cleaned_data["password"]
return credentials
# this is to set the form field in order
# careful with the indentation
def set_form_field_order(form, fields_order):
if hasattr(form.fields, 'keyOrder'):
form.fields.keyOrder = fields_order
else:
# Python 2.7+
from collections import OrderedDict
assert isinstance(form.fields, OrderedDict)
form.fields = OrderedDict((f, form.fields[f])
for f in fields_order)
Thanks.
I've been developing a mobile app to access one of my django websites. I've done the restful API using TastyPie and developed the front end using JQMobile. I've come to the part where I want to log users and have access to that logged in user.
I've done a lot of reading and searching, but I'm still really unsure what is the best approach. Ideally, I'd like to log in the user with their username and password, and then filter some of the API's returned data on this user (which I can do via the TastyPie documentation).
How have other people approached authenticating users with JQMobile and Django. I'm using PhoneGap as well so I can store returned user info from a login in the local storage if required. But I'm not quite sure how to code it all together to make request.user available on the django side when the mobile users are using the app.
So far I've come up with this from another couple of posts in the UserResource on the TastyPie side of things to sign in a user, but I'm not sure what to do once the user is signed in.
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
resource_name = 'user'
list_allowed_methods = ['get', 'post']
def override_urls(self):
return [
url(r"^(?P<resource_name>%s)/signin%s$" %
(self._meta.resource_name, trailing_slash()),
self.wrap_view('signin'), name="api_signin"),
]
def signin(self, request, **kwargs):
self.method_check(request, allowed=['post'])
# Per https://docs.djangoproject.com/en/1.3/topics/auth/#django.contrib.auth.login...
username = request.GET['username']
password = request.GET['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return self.create_response(request, {'success': True})
else:
# Return a 'disabled account' error message
return self.create_response(request, {'success': False})
else:
# Return an 'invalid login' error message.
return self.create_response(request, {'success': False})
Does anyone have any code they can share, or any pointers how to log in the users and maintain their state?
Cheers,
Ben
Phonegap is actually just a browser wrapped in some native code, which means it has the same means to persist sessions like normal web browser do - cookies!
Every ajax request being sent to the backend API can contain the sessionid cookie just like a normal GET request. The requst.user object will be available to you in your views.
You don't need to build anything special or use localstorage for that. The only thing to verify is that your domain is whitelisted so your app can access it.