Flask login/register form, error on the logic - python-3.x

I want to make a login/register form on my website, for that I found this script I reproduced from a tutorial, I adapted it but it still has an error.
If I login in the register form it's logging me, if I login in the login form, the webpage is reloading. I don't know why I have this issue but please help me!
#app.route('/', methods=['GET', 'POST'])
#app.route('/access', methods=['GET', 'POST'])
def access():
loginForm = LoginForm()
registerForm = RegisterForm()
if registerForm.validate_on_submit():
hashed_password = bcrypt.generate_password_hash(registerForm.password.data)
new_user = User(username=registerForm.username.data, password=hashed_password)
login_user(new_user)
db.session.add(new_user)
db.session.commit()
return redirect(url_for('dashboard'))
elif loginForm.validate_on_submit():
user = User.query.filter_by(username=loginForm.username.data).first()
if user:
if bcrypt.check_password_hash(user.password, loginForm.password.data):
login_user(user)
db.session.add(user)
db.session.commit()
return redirect(url_for('home'))
return render_template('access.html', loginform=loginForm, registerform=registerForm)

You are adding your users with your login form when you use the db.session.add() and db.session.commit() functions.
This is what your login page should look like:
elif loginForm.validate_on_submit():
user = User.query.filter_by(username=loginForm.username.data).first()
if user and bcrypt.check_password_hash(user.password, loginForm.password.data):
login_user(user)
return redirect(url_for('home'))

i don't know if it works, i have an other error :
ValueError: invalid literal for int() with base 10: 'None'
there is my code :
#login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))

Related

why can't I return to login html page?

#app.route('/forgotpasswd/<token>',methods=['GET', 'POST'])
def forgot_passwd(token):
form = Newpasswd(request.form)
password=form.passwd.data
if request.method == "POST" and form.validate():
try:
email = secret.loads(token, salt='forgotpasswd', max_age=3600)
except SignatureExpired:
flash("Timeout","danger")
return render_template("index.html")
finally:
cursor=Mysql.connection.cursor()
sorgu = "UPDATE users set password='{}' WHERE email= '{}' ".format(password,email)
cursor.execute(sorgu)
Mysql.connection.commit()
cursor.close()
flash("password changed","success")
return redirect(url_for("login"))
return render_template("newpassword.html",form=form)
I enter my new password on the newpasswd.html page and post it after entering it but it throws me back on the newpasswd.html page. I want to go to the login.html page.
i guess you need to change your code little bit:
#app.route('/forgotpasswd/<token>',methods=['GET', 'POST'])
def forgot_passwd(token):
form = Newpasswd() # here, you don't need to pre populate your Form object
# with the request parameters, you need to validate first
# the request parameters
if form.validate_on_submit(): # here, since you are using Forms with flast-wft
password=form.passwd.data # here
try:
email = secret.loads(token, salt='forgotpasswd', max_age=3600)
except SignatureExpired:
flash("Timeout","danger")
return render_template("index.html")
finally:
# this block wont work if "secret.loads()" function fails to return
# the email, so add an if statement block
if email is none:
cursor=Mysql.connection.cursor()
sorgu = "UPDATE users set password='{}' WHERE email= '{}' ".format(password,email)
cursor.execute(sorgu)
Mysql.connection.commit()
cursor.close()
flash("password changed","success")
else:
flash("problem","danger")
return redirect(url_for("login"))
return render_template("newpassword.html",form=form)

Redirecting after login in django rest framework

I am trying to redirect to a particular url after the user logs in. I am using django rest framework's built-in user authentication. I have tried the following code:
In urls.py, I have the following:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^register/$',views.CreateUserView.as_view(),name='user'),
url(r'^api-auth/',include('rest_framework.urls',namespace='rest_framework')),
url(r'^',include(router.urls)),
]
In settings.py, I have included the following:
LOGIN_REDIRECT_URL = '/task'
I am on the following page 'localhost/register' and after creating a user and logging in, it redirects to same 'localhost/register page'. How do I redirect to the homepage? Is there anything I am missing?
try this login view
from django.contrib.auth.forms import AuthenticationForm
def Login(request):
if request.method == 'POST':
#AuthenticationForm_can_also_be_used__
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
form = login(request,user)
messages.success(request, f' wecome {username} !!')
return redirect('index')
else:
messages.info(request, f'account done not exit plz sign in')
form = AuthenticationForm()
return render(request, 'user/login.html', {'form':form,'title':'log in'})
add this to views.py
and set any redirect this is a part of my project in case you need to see full file link
In your views.py after registration you should redirect to login page or your home page.
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
# REDIRECT here
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})
Also you can use redirection like this:
<your_app>/urls.py
from . import views
app_name = 'your_app_name'
urlpatterns = [
path('', views.index, name='index'),
in your settings.py add LOGIN_REDIRECT_URL = '<your_app_name>:index'

#flask_login.login_required not working properly

I am using flask_login for implementing auth in my flask application
Here are the unauthorized_handler and login_required enabled method
#login_manager.unauthorized_handler
def unauthorized_handler():
return redirect(url_for('login'))
# use decorators to link the function to a url
#app.route('/profile', methods=['GET'])
#flask_login.login_required
def profile():
return render_template('profile.html')
I am using firebase as my backend service
#app.route('/login', methods=['GET', 'POST'])
def login():
auth = firebase.auth()
if request.method == 'POST':
try:
user = auth.sign_in_with_email_and_password(request.form['email'], request.form['password'])
if user != None:
return redirect(url_for('profile'))
except requests.exceptions.HTTPError as e:
response = e.args[0].response
error = response.json()['error']['code']
return redirect(url_for('home'))
return render_template('login.html')
The problem is that after I login(which is successfull) the app is automatically redirected to the /login url instead of /profle.
I tried turning my debug mode off and on still not working.
It can be a case of a double redirect happening, where you first get redirected to profile, and then the login_required decorator kicks in redirecting you back to login, because from the point of view of flask_login you are not logged in yet.
You might have retrieved user credentials from firebse, but with flask_login you have to also call login_user function. (Also see Login Example of flask login's page)

how to find the username of a user from database when email is given in django

i am creating a website where a banks loggs in with its username which is a code but i wanted that bank could log in with its first_name.
i am using default user model for registration.
but authenticate() function works only with username so what i wanted to do is that bank fill their name and function finds the value of username with corrosponding name in the database and then use authenticate() function to log the bank in.
my login function in view.py
def login(request):
if request.method == 'POST':
name = request.POST.get('first_name')
password = request.POST.get('password')
username = ????????
user = authenticate(username=username, password=password)
if user:
if user.is_active and has_role(user,Banker):
auth_login(request,user)
return HttpResponseRedirect(reverse('business:dashboard'))
else:
messages.error(request,"Your account is not active")
return render(request,'accounts/bank_login.html')
else:
messages.error(request,"Invalid Username or Password")
return render(request,'accounts/bank_login.html')
else:
if request.user.is_authenticated:
return HttpResponseRedirect(reverse('business:dashboard'))
else:
return render(request,'accounts/bank_login.html')
so please anybody could tell what should i write in that username to get the value of username from database
**my models.py **
from django.db import models
from django.contrib import auth
# Create your models here.
class User(auth.models.User,auth.models.PermissionsMixin):
def __str__(self):
return self.user.username
This is slightly more complex than doing a simple query. Also, you cannot rule our that two users with the same first name will choose the same password. Here the first user found is taken
Something like this:
from django.contrib.auth.hashers import check_password
firstnameusers = User.objects.filter(first_name=name)
for usr in firstnameusers:
if check_password(password, usr.password):
username = usr.username
break
Note that you will need to write some code to handle the case where a user is not found.
I used this in my views.py file and it works perfectly
def login(request):
if request.method == 'POST':
name = (request.POST.get('name')).upper()
username = (get_user_model().objects.all().filter(first_name = name)).values("username")[0]["username"]
password = request.POST.get('password')
user = authenticate(username=username, password=password)

Why isn't my current_user authenticated in flask-login?

My goal is to make my home view (/) a login page. Once the user logs in, a different page is render depending on its role. When I login (/auth), I see that the username and password are correctly entered. It then attempts to render /, where it tells me that my user is not authenticated and renders /login. Here are the views that describe this:
Views
#app.route("/login")
def login():
return flask.render_template('login.html')
#app.route("/", methods=["GET"])
def home():
if current_user.is_authenticated:
if current_user.is_admin():
return flask.render_template('admin_index.html')
return flask.render_template('user_index.html')
logger.info("Not authenticated. Going back to login.")
return flask.render_template('login.html')
#app.route("/auth", methods=["POST"])
def auth():
username = request.form['username']
password = request.form['password']
user = db.session.query(User).filter(User.username == username).first()
logger.info(user)
logger.info("{0}: {1}".format(username, password))
print("user exists? {0}".format(str(user != None)))
print("password is correct? " + str(user.check_password(password)))
if user and user.check_password(password):
user.is_authenticated = True
login_user(user)
return flask.redirect(url_for('home'))
return flask.redirect(url_for('login'))
The problem is that flask-login's current_user.is_authenticated is always returning False after I attempt to login. My created user is correctly created and committed to the database. Below is my User model with the necessary methods as per flask-login:
User model
class User(db.Model):
"""
A user. More later.
"""
__tablename__ = 'User'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(128), unique=True)
hashed_password = db.Column(db.String(160))
admin = db.Column(db.Boolean)
def __init__(self, username, password="changeme123", admin=False):
self.username = username
self.set_password(password)
self.admin = admin
self.is_authenticated = False
def is_active(self):
return True
def is_authenticated(self):
return self.is_authenticated
def is_anonymous(self):
return False
def is_admin(self):
return self.admin
def get_id(self):
return self.id
def __repr__(self):
return '<User {0}>'.format(self.username)
def set_password(self, password):
self.hashed_password = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.hashed_password, password)
Here is the load_user function:
load_user
#login_manager.user_loader
def load_user(user_id):
try:
return User.query.get(User.id==user_id)
except:
return None
Why is current_user.is_authenticated returning False? I presumed that login_user(user) would make current_user == user, i.e., the one who is being authenticated in /auth, but it seems this is not the case.
You have a method named User.is_authenticated. Inside User.__init__, though, you set an attribute with the same name.
self.is_authenticated = False
This overrides the method. Then, whenever you check current_user.is_authenticated, you are accessing the attribute that's always false.
You should remove the assignment from __init__ and change is_authenticated to the following:
def is_authenticated(self):
return True
If you need it to be dynamic for some reason, rename the attribute so it doesn't shadow the method.
def is_authenticated(self):
return self._authenticated
Another problem is with your load_user function.
Instead of filtering for User.id==user_id, you are getting it. The user wasn't being returned because load_user is returning User.query.get(True) instead of User.query.get(user_id).
If you make the following change, it will work:
#login_manager.user_loader
def load_user(user_id):
try:
return User.query.get(user_id)
except:
return None
You don't have to create is_authenticated field in Database
Flask-Login will take care of that

Resources