'Flask check_password always return false
I create login for user in home page if user click on login then the login page is display there user enter email id and password if email id and password is correct then I redirect user to home page. Now the problem is that the user logged in whether the password is wrong or correct and another problem is that if I print user.check_password(form.password.data)
then it will return false. I do not understand what the problem is. I have config.json and there I define params so don't worry about that. set_password(self, password)
work perfectly and stored in database, all is well except check password. Here is my python code.
local_server=True
app=Flask(__name__)
app.secret_key='supper-secret-key'
login_manager=LoginManager(app)
login_manager.init_app(app)
login_manager.session_protection="strong"
db = SQLAlchemy(app)
class Users(UserMixin, db.Model):
__tablename__='users'
user_id=db.Column(db.Integer, primary_key=True)
first_name=db.Column(db.String(80), nullable=False)
last_name=db.Column(db.String(80), nullable=False)
email=db.Column(db.String(80), nullable=False)
password_hash=db.Column(db.String(255), nullable=False)
def get_id(self):
return self.user_id
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
class LoginForm(FlaskForm):
email=StringField('email', validators=[DataRequired()])
password=PasswordField('password', validators=[DataRequired()])
remember_me=BooleanField('Remember me')
submit=SubmitField('login')
@login_manager.user_loader
def load_user(user_id):
return Users.query.get(int(user_id))
@app.route("/")
def home():
return render_template("index.html", params=params)
def is_safe_url(target):
ref_url=urlparse(request.host_url, target)
test_url = urlparse(urljoin(request.host_url,target))
return test_url.scheme in ('http','https') and \
ref_url.netloc==test_url.netloc
@app.route("/login", methods=['POST','GET'])
def login():
if current_user.is_authenticated:
return render_template('index.html',params=params)
form=LoginForm()
if form.validate_on_submit():
user=Users.query.filter_by(email=form.email.data).first()
user.check_password(form.password.data)
if not user:
flash('Please check login details and try again','danger')
return redirect(url_for('login'))
print(user.check_password(form.password.data)) #False
flash('Successfully logged in','success')
login_user(user, remember=form.remember_me.data)
next=flask.request.args.get('next')
if not is_safe_url(next):
return flask.abort(400)
return flask.redirect(next or flask.url_for('home'))
return render_template("login.html", params=params, form=form)
@app.route("/logout")
def logout():
logout_user()
flash('You were logged out','warning')
return redirect(url_for('home'))
@app.route("/register")
def register():
if current_user.is_authenticated:
return render_template('index.html',params=params)
return render_template('register.html',params=params)
@app.route("/register", methods=['GET', 'POST'])
def register_post():
first_name = request.form.get('fname')
last_name = request.form.get('lname')
email = request.form.get('email')
password= request.form.get('password')
password2=request.form.get('cpassword')
if (password!=password2):
flash('Password must be same','danger')
return render_template('register.html', params=params)
users=Users.query.filter_by(email=email).first()
if users:
flash('Email address already exists','warning')
return redirect(url_for('register'))
new_user=Users(first_name=first_name,last_name=last_name,email=email)
new_user.set_password(password)
db.session.add(new_user)
db.session.commit()
return redirect(url_for('login'))
app.run(debug=True)
I have one more error If I entered wrong email id then the error is AttributeError: 'NoneType' object has no attribute 'check_password'
here is the full error code
File "C:\Python38\Lib\site-packages\flask\app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Python38\Lib\site-packages\flask\app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "C:\Python38\Lib\site-packages\flask\app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Python38\Lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Python38\Lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:\Python38\Lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Python38\Lib\site-packages\flask\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Python38\Lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Python38\Lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Python38\Lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "D:\tuts\PythonFlask\ThirdFlask.py", line 134, in login
user.check_password(form.password.data)
AttributeError: 'NoneType' object has no attribute 'check_password'
Here is the code of login.html
{% extends "layout.html" %}
{% block body %}
<form method="POST" action="/login">
<div class="overlay"></div>
<div class="container">
<div class="row">
<div class="card" style="margin: auto; margin-top: 100px; width: 25rem;">
<!--message flashing started here-->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages%}
{% for category,message in messages%}
<div class="alert alert-{{category}} alert-dismissible fade show" role="alert">
{{message}}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endfor %}
{% endif %}
{% endwith %}
<div class="card-body">
<form class="form" method="POST" action="/login">
{{ form.csrf_token }}
{{ form.name }}
<label>Email</label><br>
<input type="email" class="form-control" name="email" placeholder="email" required><br>
<label>Password</label><br>
<input type="password" class="form-control" name="password" placeholder="password" required><br><br>
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember_me"> Remember me
</label>
</div>
<input type="submit" class="btn btn-primary btn-block btn-lg" value="login">
</form>
<p>Not a member? <a href="/register">Create Account</a></p>
</div>
</div>
</div>
</div>
<!-- Main Content -->
{% endblock %}
Help me to solve this problem and thanks in advance :)
Solution 1:[1]
You need to rearrange:
@app.route("/login", methods=['POST','GET'])
def login():
if current_user.is_authenticated:
return render_template('index.html',params=params)
form=LoginForm()
if form.validate_on_submit():
user=Users.query.filter_by(email=form.email.data).first()
# dont check password if user with that email does not exist
if not user:
flash('Please check login details and try again','danger')
return redirect(url_for('login'))
if user.check_password(form.password.data):
flash('Successfully logged in','success')
login_user(user, remember=form.remember_me.data)
next=flask.request.args.get('next')
if not is_safe_url(next):
return flask.abort(400)
return flask.redirect(next or flask.url_for('home'))
else:
flash('incorrect password','fail')
return render_template("login.html", params=params, form=form)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | GAEfan |