I am trying to execute one of the url of urls.py with urllib in django view function. After execution i got error like
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 411: Length Required
Is this possible to execute url with urllib inside django view function.
#login_required(login_url='http://domain/user/login?destination=apps/member/change_password')
def change_password(request):
'''Form for user to change their password'''
form = SetPasswordForm(user=request.user, data=request.POST or None)
if form.is_valid():
form.save()
ob = urllib.request.urlopen(url='http://domain/login/', data=request)
messages.success(request, 'Your password has been succesfully updated!')
return redirect('hq:profile')
return render(request, 'registration/password_change_form.html',
{'form': form})
when i execute urllib
Yes it is possible but keep in mind, that the time of that request will add up to your loading time.
If you do that from within the same django system you should think, if there would be a better solution.
In your case it may eventually use:
from django.contrib.auth import authenticate
authenticate(username, password)
I have solved my problem by modifying as below.
from django.contrib.auth import login
#login_required(login_url='http://domain/user/login?destination=apps/member/change_password')
def change_password(request):
'''Form for user to change their password'''
form = SetPasswordForm(user=request.user, data=request.POST or None)
if form.is_valid():
user = form.save()
user.is_active = True
user.save()
user.backend = "django.contrib.auth.backends.ModelBackend"
login(request, user)
messages.success(request, 'Your password has been succesfully updated!')
return redirect('hq:profile')
return render(request, 'registration/password_change_form.html',
{'form': form})
Related
I am using Django to build a web app. I am using Vue JS for the frontend. My problem is when ever I use csrf_protect its showing 403 error
My views:
#csrf_protect
def SignUpView(request):
if request.method == "POST":
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username, password = form.cleaned_data.get('username'), form.cleaned_data.get('password1')
new_user = authenticate(username = username, password = password)
login(request, new_user)
return redirect('/')
else:
form = SignUpForm()
return render(request, 'Accounts/SignUp.html', {'form':form})
#csrf_protect
def validateUsername(request):
username = request.GET.get('username', None)
usernameRegEx = r'^[a-zA-Z0-9#+-_.#]*$'
usernameRegExResult = {
'valid' : bool(re.search(usernameRegEx, username, re.M|re.I)),
'is_taken' : User.objects.filter(username=username).exists()
}
return JsonResponse(usernameRegExResult)
I read the Django docs which says I can use csrf_protect decorator above my view but in my case its not working. Somebody please help.
CSRF is a protection that prevents cross site request forgery. It works by generating an unique token that identify the form. So if you send data to your server without the token it gave you (through cookies for instance) it will not accept it.
If you have the CSRF middleware turned on you should not need CSRF protect decorator!
I have an app where I'm trying to allow login by username alone. I've been doing this:
#login_required(login_url='/login')
def index(request):
# bunch of queries to provide to the add_rule.html via context
return render(request, "index.html", context=context)
def user_login(request):
if request.method == 'GET':
return render(request, 'registration/login.html')
else:
username = request.POST.get('username')
user = authenticate(username=username) # custom function
login(request, user)
# somehow return the above previous index() function with the request that has updated login/username information
I'm not exactly sure how I can render the index.html template with the request that now has the login information. The docs are not clear on how things get redirected after login. I apologize if there is not enough information.
The login_required [Django-doc] has a redirect_field_name parameter. This specifies the name of the GET parameter that will encode the path from which the redirection was made. By default, that parameter is 'next'.
You can thus redirect with:
from django.http import HttpResponseRedirect
def user_login(request):
if request.method == 'GET':
return render(request, 'registration/login.html')
else:
username = request.POST.get('username')
user = authenticate(username=username) # custom function
login(request, user)
return HttpResponseRedirect(self.request.GET.get('next', ''))
You will however have to implement some extra logic in case the authentication fails, etc.
The LoginView [Django-doc] has a slightly more complex implementation [GitHub] that aims to fetch this from the POST parameters, GET parameters, and does some validation to check if the path is safe.
BACKGROUND:
I'm using the versatile django-brake for rate limiting in my Django app. I now need to configure it to limit brute force login attempts in my app too.
The way to do that is to decorate the login view with the decorator ratelimit(field='username') and adding was_limited = getattr(request, 'limited', False) inside the view. was_limited is True if the same username (OR IP) is used >5 times/min. One can then redirect offending users, etc.
SCENARIO:
Currently, I'm using the login function in django.contrib.auth.views. I can decorate this function in my urls.py. But I can't include was_limited = getattr(request, 'limited', False) inside the function that way. And that is mission critical, since only once that flag is True can I take action against the offending user.
QUESTION:
So what's the best way for me to decorate and extend this function to include the above functionality? Do I need to override the whole thing, and if so, how? Please advise. I can directly write the required code in django.contrib.auth.views, but that's a hack.
Being a beginner, I'm trying to come up with the best way to deal with a situation like this. An illustrative example would be nice.
For reference, I'm including django.contrib.auth.views.login below:
#sensitive_post_parameters()
#csrf_protect
#never_cache
def login(request, template_name='registration/login.html',
redirect_field_name=REDIRECT_FIELD_NAME,
authentication_form=AuthenticationForm,
current_app=None, extra_context=None):
"""
Displays the login form and handles the login action.
"""
redirect_to = request.REQUEST.get(redirect_field_name, '')
if request.method == "POST":
form = authentication_form(data=request.POST)
if form.is_valid():
# Ensure the user-originating redirection url is safe.
if not is_safe_url(url=redirect_to, host=request.get_host()):
redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL)
# Okay, security check complete. Log the user in.
auth_login(request, form.get_user())
if request.session.test_cookie_worked():
request.session.delete_test_cookie()
return HttpResponseRedirect(redirect_to)
else:
form = authentication_form(request)
request.session.set_test_cookie()
current_site = get_current_site(request)
context = {
'form': form,
redirect_field_name: redirect_to,
'site': current_site,
'site_name': current_site.name,
}
if extra_context is not None:
context.update(extra_context)
return TemplateResponse(request, template_name, context,
current_app=current_app)
All the work is already done in the decorator, by the looks of things. The examples show adding was_limited if you want to do something extra inside the view to say that requests were previously limited, but there's certainly no need to do so and it won't have any effect on the functionality.
I tried this and its working. See the reference from https://docs.djangoproject.com/en/1.10/topics/auth/default/
def my_login(request,*args,**kwargs):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
if username and password:
user = authenticate(username=username, password=password)
if user:
login(request, user)
return redirect('/home')
else:
return render(request, 'login.html')
else:
return render(request, 'login.html')
return render(request, 'login.html')
What are the options when you want to return the user to the same page in Django and what are the pros/cons of each?
Methods I know:
HTTP_REFERER
GET parameter containing the previous URL
Session data to store the previous URL
Are there any other?
One of the way is using HTTP_REFERER header like as below:
from django.http import HttpResponseRedirect
def someview(request):
...
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
Not sure of cons of this!
100% working Example
For Class Based View and Function:
from django.http import HttpResponseRedirect
...
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
or
from django.http import HttpResponseRedirect
...
return HttpResponseRedirect(self.request.META.get('HTTP_REFERER'))
Example -
class TaskNotificationReadAllView(generic.View):
def get(self, request, *args, **kwargs):
TaskNotification.objects.filter(assigned_to=request.user).update(read=True)
print(request.META.get('HTTP_REFERER'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
While the question and answer is old, I think it's lacking a few options. I have not find any cons with the methods, I would be happy to know if there are any?
request.path_info
request.get_full_path()
request.build_absolute_uri()
from django.shortcuts import redirect
redirect(request.path_info) # No query parameters
redirect(request.build_absolute_uri()) # Keeps query parameters
redirect(request.get_full_path()) # Keeps query parameters
In django view suppose you are not logged in but click on some content that content trigger some url like /board/2/new_topic then #login_required will redirect you to login page with this url
http://localhost:8000/signin/?next=/boards/2/new_topic/
so our aim is redirect to http://localhost:8000/boards/2/new_topic/ page after successful login so one line we will have to add
if 'next' in request.GET:
return redirect(request.GET['next'])
then if it next is there then it will redirect according to that other normal redirect .
Views.py :
def signin(request):
if request.method == "POST":
user_login_form = UserLoginForm(request.POST)
email = request.POST['email']
password = request.POST['password']
user = authenticate(request, email=email, password=password)
if user and user.is_active:
login(request, user)
if 'next' in request.GET:
return redirect(request.GET['next'])
else:
return redirect('home')
else:
return render(request, 'signin.html', context={'form': user_login_form})
else:
user_login_form = UserLoginForm()
return render(request, 'signin.html', context={'form': user_login_form})
I'm trying to have a user login automatically as soon as they register. They have just input their desired username and two matching passwords and I would like to grant access to the site with no more friction. But my current view with an authenticate followed by a login using authenticate's user object doesn't work i.e. the view redirects to the profile page after register, but the profile page is #login_required decorator protected, and so redirects because the login was unsuccessful. I have widely debugged and looked around.
I've tried everything I can think of short of resorting to a third-party registration app. People have suggested there's a problem/peculiarity with the backends or something, but I just can't see why I can't register, auth and login in one view.
views.py (relevant parts)
#login_required
def user(request, user_id):
profile_user = User.objects.get(id=user_id)
context = RequestContext(request)
context['profile_user'] = profile_user
return render_to_response('profile.html', context)
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
new_user = authenticate(username = request.POST['username'],
password = request.POST['password1'])
if new_user is not None:
login(request, new_user)
context = RequestContext(request)
context['user_id'] = new_user.id
context['new_user'] = new_user
url = '/user/%s/' % new_user.id
return HttpResponseRedirect(url)
else:
form = UserCreationForm()
return render_to_response("registration/register.html", {'form': form},
context_instance=RequestContext(request))
How do you deal with this?
You can make it work by:
Redirecting to an intermediate template through simple view, it will set the session cookie on client side, you can show a message like "Registration completed. logging in..."
Redirect to profile page after a small 3-5 seconds time out. This time, request will carry authentication cookie, profile page will be accessible.