I am creating /auth/ page on my Django Rest Framework site. And I can not save session id.
Have i create this cookie or its creating automatically?
My auth view:
class AuthView(APIView):
permission_classes = (permissions.AllowAny,)
renderer_classes = [TemplateHTMLRenderer]
#csrf_exempt
def get(self, request):
return render(request, 'login.html', {})
#csrf_exempt
def post(self, request):
serializer = AuthFormSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
data = serializer.data
username = data.get('username')
password = data.get('password')
if username is None or password is None:
return Response({'error': 'Please provide both username and password'},
status=HTTP_400_BAD_REQUEST, template_name='login.html')
user = authenticate(username=username, password=password)
if not user:
return Response({'error': 'Invalid Credentials'},
status=HTTP_404_NOT_FOUND, template_name='login.html')
self.token, _ = Token.objects.get_or_create(user=user)
user_token = Token.objects.get(user_id = user.pk)
if (datetime.now() - user_token.created.replace(tzinfo=None)).days > 10:
Token.objects.update(user_id=user.pk, key=Token.generate_key(user.pk), created = datetime.now())
context = {'token': self.token.key}
# return Response(, status=HTTP_201_CREATED, template_name='')
return HttpResponse(json.dumps(context), content_type="application/json")
I forgot write login(request, user) , do not repeat my mistakes xD
Related
i was following a tutorial and after finishing it i came across and error which should only be shown if the form i have submitted is invalid. I am using recaptcha and several other apis
these are few of my functions
result = "Error"
message = "There was an error, please try again"
class AccountView(TemplateView):
'''
Generic FormView with our mixin to display user account page
'''
template_name = "users/account.html"
#method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
def is_ajax(request):
return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
def profile_view(request):
'''
function view to allow users to update their profile
'''
user = request.user
up = user.userprofile
form = UserProfileForm(instance = up)
if request.is_ajax():
form = UserProfileForm(data = request.POST, instance = up)
if form.is_valid():
obj = form.save()
obj.has_profile = True
obj.save()
result = "Success"
message = "Your profile has been updated"
else:
message = FormErrors(form)
data = {'result': result, 'message': message}
return JsonResponse(data)
else:
context = {'form': form}
context['google_api_key'] = settings.GOOGLE_API_KEY
context['base_country'] = settings.BASE_COUNTRY
return render(request, 'users/profile.html', context)
class SignUpView(AjaxFormMixin, FormView):
'''
Generic FormView with our mixin for user sign-up with reCAPTURE security
'''
template_name = "C:/Users/adity\OneDrive/Documents/Coding/python/py_tutorial/djangotutorial/googleapi project/googapiproj/templates/users/sign_up.html"
form_class = UserForm
success_url = "/"
#reCAPTURE key required in context
def is_ajax(request):
return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["recaptcha_site_key"] = settings.RECAPTCHA_PUBLIC_KEY
return context
#over write the mixin logic to get, check and save reCAPTURE score
def form_valid(self, form):
response = super(AjaxFormMixin, self).form_valid(form)
if request.is_ajax():
token = form.cleaned_data.get('token')
captcha = reCAPTCHAValidation(token)
if captcha["success"]:
obj = form.save()
obj.email = obj.username
obj.save()
up = obj.userprofile
up.captcha_score = float(captcha["score"])
up.save()
login(request, obj, backend='django.contrib.auth.backends.ModelBackend')
#change result & message on success
result = "Success"
message = "Thank you for signing up"
data = {'result': result, 'message': message}
return JsonResponse(data)
return response
class SignInView(AjaxFormMixin, FormView):
'''
Generic FormView with our mixin for user sign-in
'''
template_name = "C:/Users/adity\OneDrive/Documents/Coding/python/py_tutorial/djangotutorial/googleapi project/googapiproj/templates/users/sign_in.html"
form_class = AuthForm
success_url = "/"
def is_ajax(request):
return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
def form_valid(self, form):
response = super(AjaxFormMixin, self).form_valid(form)
if request.is_ajax():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
#attempt to authenticate user
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
result = "Success"
message = 'You are now logged in'
else:
message = FormErrors(form)
data = {'result': result, 'message': message}
return JsonResponse(data)
return response
def sign_out(request):
'''
Basic view for user sign out
'''
logout(request)
return redirect(reverse('users:sign-in'))
I am trying to create role based login system but it continuously showing the mentioned error
N.B: I'm new to django
def login_view(request):
form = AuthenticationForm()
if request.method=='POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user is not None and user.is_student==True:
login(request,user)
if request.GET.get('next'):
return render(request.GET.get('next'))
else:
return redirect(homepage)
Every view in django should return an instance of HttpResponse object, therefore you need to cover all edge cases, e.g.:
def login_view(request):
form = AuthenticationForm()
if request.method=='POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user is not None and user.is_student==True:
...
# Return 401 if the user is None or the user is not a student
return HttpResponse('Unauthorized', status=401)
# Default HttpResponse on `GET` requests
return render(request, '<your_template.html>', {'form': form})
I created login authentication in Rest Api it Retrieves token key in postman. Right now I need the username of the person associated with a token key.
how to do that ?
# views.py
class LoginView(APIView):
def post(self, request):
serializer = LoginSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data["user"]
django_login(request, user)
token, created = Token.objects.get_or_create(user=user)
return Response({"token": token.key }, status=200)
# serializers.py
class LoginSerializer(serializers.Serializer):
username = serializers.CharField()
password = serializers.CharField()
def validate(self, data):
username = data.get("username", "")
password = data.get("password", "")
if username and password:
user = authenticate(username=username, password=password)
if user:
if user.is_active:
data["user"] = user
else:
msg = "User is deactivated."
raise exceptions.ValidationError(msg)
else:
msg = "Unable to login with given credentials."
raise exceptions.ValidationError(msg)
else:
msg = "Must provide username and password both."
raise exceptions.ValidationError(msg)
return data
After the login authentication the method(Authentication method) will return the user, so you can fetch the user data like this,
username = user.username
Example:
class LoginView(APIView):
def post(self, request):
serializer = LoginSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.validated_data["user"]
django_login(request, user)
token, created = Token.objects.get_or_create(user=user)
return Response({"token": token.key , "username":user.username},status=200)
I wrote some code for custom authentication with this structure:
serializers.py
class LoginSerializer(serializers.Serializer):
first_token = serializers.CharField()
phonenumber = serializers.CharField()
token = serializers.CharField(max_length=255, read_only=True)
views .py
class LoginView(APIView):
serializer_class = LoginSerializer
permission_classes = (AllowAny,)
def post(self, request, format=None):
phonenumber = request.data.get('phonenumber', None)
first_token = request.data.get('first_token', None)
try:
x = User.objects.get(phonenumber=phonenumber)
except x.DoesNotExist:
return Response('user does not exists')
if first_token == x.first_token.token:
user = authenticate(phonenumber=phonenumber)
login_user = login(request, user)
user_info = {
'phonenumber': user.phonenumber,
'username': user.username,
'token': user.token,
'is_admin':user.is_admin,
}
return Response(user_info, status=status.HTTP_200_OK)
urls.py
urlpatterns = [
re_path(r'^login/$', views.LoginView.as_view(), name='login'),
]
so, authentication and login is successful and user logs in. but when i try to go another page testframework doesnt store the authentication. I made a custom authentication already .
auth.py
class PhoneAuthentication(authentication.BaseAuthentication):
authentication_header_prefix = 'Token'
def authenticate(self, request):
request.user = None
auth_header = authentication.get_authorization_header(request).split()
auth_header_prefix = self.authentication_header_prefix.lower()
if not auth_header:
return None
if len(auth_header) == 1:
return None
elif len(auth_header) > 2:
return None
prefix = auth_header[0].decode('utf-8')
token = auth_header[1].decode('utf-8')
if prefix.lower() != auth_header_prefix:
return None
return self._authenticate_credentials(request, token)
def _authenticate_credentials(self, request, token):
try:
payload = jwt.decode(token, settings.SECRET_KEY)
except:
raise exceptions.AuthenticationFailed("invalid authentication . could not decode token")
try:
user = User.objects.get(pk=payload['id'])
except User.DoesNotExist:
raise exceptions.AuthenticationFailed('No such user')
return(user, token)
I think the best way to do it is to subscribe the view ObtainAuthToken that is default of DRF.
Why the authentication is not working with custom model "Consultants".i have tried a lot but it not working
models.py
class Consultants(models.Model):
# user=models.OneToOneField(User)
consul_id=models.IntegerField(default=0,primary_key=True)
first_name=models.CharField(max_length=255,blank=True,null=True)
last_name=models.CharField(max_length=255,blank=True,null=True)
email=models.EmailField(max_length=255,blank=True,null=True)
username=models.CharField(max_length=255,blank=True,null=True)
password=models.CharField(max_length=50,blank=True,null=True)
consul_pic=models.ImageField(upload_to="/home/cp/Documents/consul_pic",blank=True,null=True)
mobile_no=models.CharField(max_length=255,blank=True,null=True)
)
last_login=models.DateTimeField(default=datetime.now,blank=True,null=True)
is_active=models.BooleanField(default=False)
def __str__(self):
return self.first_name or u''
views.py
def login_user(request):
context = RequestContext(request)
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
print type(username)
try:
user = authenticate(username=username, password=password)
print 'chala'
if user.is_active:
user.backend = 'django.contrib.auth.backends.ModelBackend'
login(request, user)
return HttpResponse("welcome......you are succesfuly log in")
else:
return HttpResponse("Your account is disabled.")
except ObjectDoesNotExist:
return HttpResponse("INvalid User")
else:
return render_to_response('login.html', {}, context)
when i try to authenticate it return None.
it is the correct way which i try to login please help me in it.
that is not correct way of customizing user model
you should try like this
reference : https://docs.djangoproject.com/en/1.9/topics/auth/customizing/
from django.contrib.auth.models import (AbstractBaseUser,
PermissionsMixin,
UserManager)
class Consultants(AbstractBaseUser, PermissionsMixin):
consul_id=models.IntegerField(default=0,primary_key=True)
first_name=models.CharField(max_length=255,blank=True,null=True)
last_name=models.CharField(max_length=255,blank=True,null=True)
email=models.EmailField(max_length=255,blank=True,null=True)
username=models.CharField(max_length=255,blank=True,null=True)
password=models.CharField(max_length=50,blank=True,null=True)
consul_pic=models.ImageField(upload_to="/home/cp/Documents/consul_pic",blank=True,null=True)
mobile_no=models.CharField(max_length=255,blank=True,null=True))
last_login=models.DateTimeField(default=datetime.now,blank=True,null=True)
is_active=models.BooleanField(default=False)
objects = UserManager()
def __str__(self):
return self.first_name or u''