Hey everyone I have a couple questions in regards to refactoring some old api endpoints as far as authentication goes. I have a view for example...
#csrf_exempt
# PARAMETERS: username, password
def submit_offer(request):
"""Submit an offer"""
username = request.GET.get("username")
password = request.GET.get("password")
# Authenticate user to set instance.user value into BuyerForm
user = authenticate(username=username, password=password)
if not user:
# Always want our potential Buyer to be logged in & authenticated
return JsonResponse({'message': 'Please login to continue.'})
if request.method == 'POST':
form = BuyerForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save(commit=False)
# sets current user as Buyer.user
instance.user = user
instance.save()
return JsonResponse({'success': True}, status=200)
else:
data = form.errors.as_json()
return JsonResponse(data, status=400, safe=False)
else:
return JsonResponse(data={'status': 403})
Now every view that uses a form, and needs to grab the instance.user, has the same lines of code below...now I thought using request.user would do the job, but when testing that way I am getting back an AnonymousUser, which is kind of confusing me?
username = request.GET.get("username")
password = request.GET.get("password")
# Authenticate user to set instance.user value into BuyerForm
user = authenticate(username=username, password=password)
Now is there a better way to authenticate the user, like in a regular django view using request.user, rather than having to manually authenticate the user in each view? (edited)
password = request.GET.get("password").
This is very vulnerable way to design a django app.
Please see
Accessing Username and Password in django request header returns None
BTW, write a custom middle ware and put your code there.
username = get_username_from_header
password = get_password_from_header
# Authenticate user to set instance.user value into BuyerForm
user = authenticate(username=username, password=password)
# Attach user to request
request.user = user
As each request are being passed through the middle-ware, you can access the user from each view.
Related
I am trying as hard as I can to learn to concept of authentication within the Django framework. I am reading the documentation and trying to code similar which will help me get the subject. At the moment I am trying to implement a simple login which redirects to a page. If the user is logged in he should see a message other wise he should see a different message. This is my code.
I have made a simple login form
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput())
this is my login view
def login_view(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('/users/success/')
else:
return redirect('/users/success/')
else:
form = LoginForm()
return render(request, 'testauth/login.html', {'form': form})
(I know the above code is a little bit redundant ... at the moment this is not so important)
and this is the success view
def success_view(request):
print(request.user)
if request.user.is_authenticated:
return HttpResponse("logged in")
else:
return HttpResponse("you are not logged in")
The problem is, I always get the "logged in" message even with users which do not exist. I tried restarting the server my cache is disabled ... I have no idea why is this happening. Why is this happening?
(p.s. I do not want to set in the settings.py a login success url. I want to do everything manually because I am struggling a lot with this topic and I want to make sure that I truly understand everything)
I am trying to create a user login. I am registering the user through django's admin page. Username and passwords are entered correctly.
Also I have tried adding authentication backends to settings.py
I have tried multiple ways but couldn't get it to work.
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
My code looks like below :
models.py :
class Account(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
views.py:
def login(request):
if request.method == 'POST':
username = request.POST.get('user')
password = request.POST.get('pass')
user = authenticate(username=username,
password=password) ----------> None
if user:
if user.is_active():
login(request, user)
return HttpResponseRedirect(reverse('index'))
else:
return HttpResponse('Account not active')
else:
print('Someone tried to login and failed ')
print('Username {} and passowrd {}'.format(username, password))
return HttpResponse('Invalid login details supplied!!')
else:
return render(request,'account/login.html', {})
The username and password from the below ones are coming as empty so it is giving none
username = request.POST.get('user')
password = request.POST.get('pass')
Try to inspect the element from HTML to find the name of the fields from which the data is coming from the template or print the values of username and password variables to cross verify.
use request.POST.get('username'), request.POST.get('password1') but as told it totally depends on the html template. It is safer to clean the data and then go for authentication.
Django has inbuilt Class Based Views for the same purpose. Give them a try
i'm writing a django / angularjs application, and i'm trying to use the #permission_required for user permission authorization.
I'm returning from the client side both headers- sessionId and csrf token, and yet the #permission_required method user, is anonymousUser, although when i'm logging in the user, i use - login(request, user) method, and the user arg is updated to the current user:
#api_view(['GET', 'POST', 'DELETE'])
def log_in_view(request):
body = request.body
json_body = json.loads(body)
email = json_body.get("email")
password = json_body.get('password')
user = authenticate(email=email, password=password)
session = request.session
if user is not None:
request.session['email'] = email
request.session['password'] = password
session.set_expiry(900)
session.save()
session_key = session.session_key
login(request, user)
crcf = get_token(request)
response_body = {}
response_body.update({"session_key" : session_key})
response_body.update({"csrf" : crcf})
return HttpResponse(json.dumps(response_body), content_type="text/json", status=200)
else:
return HttpResponse("could not authenticate user", content_type="text/plain", status=401)
does anyone have any idea what am i doing wrong?
cheers
you dont need all those stuff to login the user. I mean you dont need to set up session manually, either return csrf token.
#api_view(['GET', 'POST', 'DELETE'])
def log_in_view(request):
body = request.body
json_body = json.loads(body)
email = json_body.get("email")
password = json_body.get('password')
user = authenticate(email=email, password=password)
if user:
login(request, user)
response_body = {}
response_body['user'] = user
return HttpResponse(json.dumps(response_body), content_type="text/json", status=200)
else:
return HttpResponse("could not authenticate user", content_type="text/plain", status=401)
By use of #api_view I'm assuming that you're using Django REST Framework.
Each api view of django rest framework don't rely by default on django authentication. If you want your view to use django authentication, you should add proper #authentication_classes(...) decorator to your view or specify it globally in your settings.py file.
I have a login view like this:
def login_backend(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
state = "Username or Password Incorrect!"
if user is not None:
login(request, user)
return HttpResponseRedirect('/overview/')
else:
captcha = CaptchaField()
return render_to_response('login_backend.html', {'state':state,
'captcha':captcha }, context_instance=RequestContext(request))
else:
return render_to_response('login_backend.html', context_instance=RequestContext(request))
Now, if the user is wrong for more than one time, captcha is shown. However, I want to show captcha only when the user enters wrong password for more than 3 times. I think I can keep the track of the user attempt and if attempt > 3, I can show the captcha but I don't know how to implement it. How can I do this?
You can set the attempt variable in session data this way:
request.session['attempt'] = 1
and use session as a regular dict, which means using tools such as
if 'attempt' in request.session:
I've view like this. It worked. I'm new to django. Can you please help me to improve this code? thank you
def getAPI(request):
username = request.GET.get('username')
password = request.GET.get('password')
#TODO Match user and password
if username:
user = User.objects.get(username__exact=username)
is_exist = user.check_password(password)
if is_exist == True:
api_key = ApiKey.objects.get(id=user.id)
else:
error_message = 'username or password is invalid.'
return render_to_response('details.html',locals(),
context_instance=RequestContext(request)
)
if username and password does not exist Then I want to print error message. Otherwise I want to print ApiKey. thanks
Do you mean "print" (in which case just use python's print function) or do you want to return it in the response? If the latter, read up about django templates and passing variables to render_to_response.
Also, sticking a password as a GET variable is a bit of a bad idea, since it'll be visible on the URL:
http://example.com/whatever?username=me&password=s3cr3t
User/pass info should normally be sent via POST from a form. But maybe you're not that bothered about security.
Here's the basic template to authenticate a user:
from django.contrib.auth import authenticate
def my_view(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
# User is authenticated - return api key
else:
# Return a 'disabled account' error message
else:
# Return an 'invalid login' error message.