It has taken us quite a bit, but here we are: the login page! If you have not already, then you should register a few users, and remember one of them to test our login page when we're done.
We already have the login template, which we can just keep, but now the verification process needs to verify against users in our database, rather than against the hard-coded admin user.
Part of __init__.py file
@app.route('/login/', methods=["GET","POST"]) def login_page(): error = '' try: c, conn = connection() if request.method == "POST": data = c.execute("SELECT * FROM users WHERE username = (%s)", thwart(request.form['username'])) data = c.fetchone()[2] if sha256_crypt.verify(request.form['password'], data): session['logged_in'] = True session['username'] = request.form['username'] flash("You are now logged in") return redirect(url_for("dashboard")) else: error = "Invalid credentials, try again." gc.collect() return render_template("login.html", error=error) except Exception as e: #flash(e) error = "Invalid credentials, try again." return render_template("login.html", error = error)
Here, we're using the connection file we wrote to connect to the database (dbconnect.py), which has the function called connection.
We're doing the same check as before for the POST method. If so, we're then going to query the database to see if the username the person has input is in the database, not forgetting to use thwart to protect against SQL injection.
Next, if the username exists, we then compare the attempted username to the hashed password that we have on record, verifying whether or not the stored hash's source is the same as what the user tried as a password.
If so, then we're logging in the user via Flask's session functionality, then we're sending them to the dashboard, since they're all done with the login page.
If anything goes wrong, the error we give is just "Invalid credentials, try again." You can give custom errors, like that username doesn't exist, or wrong password, but someone attempting to hack your website or the username can use this to their advantage, knowing exactly where they have gone wrong.