Python Flask Mysql Login Logout with Remember Me Option and Password Hash
This tutorial we are going to see how to give users to remember their login credentials through cookie and password in the database is in hash
Database Table
CREATE TABLE `user_test_flask` (
`id` int(10) UNSIGNED NOT NULL,
`name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`username` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL,
`email` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`pwd` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`admin` tinyint(4) DEFAULT '0',
`last_login` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Dumping data for table `user_test_flask`
INSERT INTO `user_test_flask` (`id`, `name`, `username`, `email`, `pwd`, `admin`, `last_login`) VALUES
(1, 'Cairocoders Ednalan', 'test2', 'test2@gmail.com', 'pbkdf2:sha256:150000$QYp0kc3v$88fb99cca1479b212dfdf7f58199e7207693a9cc187065b7dbe7837f3cd4872c', 0, '2020-02-22 02:26:21')
ALTER TABLE `user_test_flask`
ADD PRIMARY KEY (`id`);
ALTER TABLE `user_test_flask`
MODIFY `id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
Login
Email : test2@gmail.com
Password : test2
#app.py from flask import Flask, render_template, url_for, flash, session, request, redirect, make_response from flaskext.mysql import MySQL import pymysql from datetime import timedelta from werkzeug import generate_password_hash, check_password_hash app = Flask(__name__) app.secret_key = "caircocoders-ednalan-2020" app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(minutes=10) global COOKIE_TIME_OUT #COOKIE_TIME_OUT = 60*60*24*7 #7 days COOKIE_TIME_OUT = 60*5 #5 minutes #Database Configuration mysql = MySQL() # MySQL configurations app.config['MYSQL_DATABASE_USER'] = 'root' app.config['MYSQL_DATABASE_PASSWORD'] = '' app.config['MYSQL_DATABASE_DB'] = 'testingdb' app.config['MYSQL_DATABASE_HOST'] = 'localhost' mysql.init_app(app) @app.route('/') def index(): if 'email' in session: username = session['email'] return 'Logged in as ' + username + '<br>' + "<b><a href = '/logout'>Click here to logout</a></b>" return "You are not logged in <br><a href = '/login'></b>" + "click here to login</b></a>" @app.route('/login') def login(): return render_template('login_logout_with_rememberme.html') @app.route('/submit', methods=['POST']) def login_submit(): conn = None cursor = None _email = request.form['inputEmail'] _password = request.form['inputPassword'] _remember = request.form.getlist('inputRemember') if 'email' in request.cookies: username = request.cookies.get('email') password = request.cookies.get('pwd') conn = mysql.connect() cursor = conn.cursor() sql = "SELECT * FROM user_test_flask WHERE email=%s" sql_where = (username,) cursor.execute(sql, sql_where) row = cursor.fetchone() if row and check_password_hash(row[4], password): print(username + ' ' + password) session['email'] = row[3] cursor.close() conn.close() return redirect('/') else: return redirect('/login') # validate the received values elif _email and _password: #check user exists conn = mysql.connect() cursor = conn.cursor() sql = "SELECT * FROM user_test_flask WHERE email=%s" sql_where = (_email,) cursor.execute(sql, sql_where) row = cursor.fetchone() if row: if check_password_hash(row[4], _password): session['email'] = row[3] cursor.close() conn.close() if _remember: resp = make_response(redirect('/')) resp.set_cookie('email', row[3], max_age=COOKIE_TIME_OUT) resp.set_cookie('pwd', _password, max_age=COOKIE_TIME_OUT) resp.set_cookie('rem', 'checked', max_age=COOKIE_TIME_OUT) return resp return redirect('/') else: flash('Invalid Password!') return redirect('/login') else: flash('Invalid Email Or Password!') return redirect('/login') else: flash('Invalid Email Or Password!') return redirect('/login') @app.route('/logout') def logout(): if 'email' in session: session.pop('email', None) return redirect('/') if __name__ == '__main__': app.run(debug=True)
//login_logout_with_rememberme.html <html> <title>Python Flask Mysql Login Logout with Remember Me Option and Password Hash</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.1/css/all.css"> </head> <body> <div class="container h-100"> <h4 align="center">Python Flask Mysql Login Logout with Remember Me Option and Password Hash</h4> <div class="d-flex justify-content-center h-100"> <div class="user_card"> <div class="d-flex justify-content-center"> <div class="brand_logo_container"> <img src="{{ url_for('static', filename='img/logo.png') }}" class="brand_logo" alt="Logo"> </div> </div> <div class="d-flex justify-content-center form_container"> <form method="post" action="/submit"> <div class="input-group mb-3"> <div class="input-group-append"> <span class="input-group-text"><i class="fas fa-user"></i></span> </div> <input type="text" name="inputEmail" value="{% if 'email' in request.cookies %} {{ request.cookies.get('email') }} {% endif %}" placeholder="Email" required class="form-control input_user"> </div> <div class="input-group mb-2"> <div class="input-group-append"> <span class="input-group-text"><i class="fas fa-key"></i></span> </div> <input type="password" name="inputPassword" value="{% if 'pwd' in request.cookies %} {{ request.cookies.get('pwd') }} {% endif %}" placeholder="Password" autocomplete="off" required class="form-control input_pass" value=""> </div> <div class="form-group"> <div class="custom-control custom-checkbox"> <input type="checkbox" name="inputRemember" checked="{% if 'rem' in request.cookies %} {{ request.cookies.get('rem') }} {% endif %}" autocomplete="off" class="custom-control-input" id="customControlInline"> <label class="custom-control-label" for="customControlInline">Remember me</label> </div> </div> <div class="d-flex justify-content-center mt-3 login_container"> <input type="submit" value="Login" class="btn login_btn"> </div> </form> </div> <div class="mt-4"> <div> {% with messages = get_flashed_messages() %} {% if messages %} {% for message in messages %} <div class="alert alert-danger" role="alert">{{ message }}</div> {% endfor %} {% endif %} {% endwith %} </div> <div class="d-flex justify-content-center links"> Don't have an account? <a href="#" class="ml-2">Sign Up</a> </div> <div class="d-flex justify-content-center links"> <a href="#">Forgot your password?</a> </div> </div> </div> </div> </div> <style> body, html { margin: 0; padding: 0; height: 100%; background: #60a3bc !important; } .user_card { height: 450px; width: 350px; margin-top: auto; margin-bottom: auto; background: #f39c12; position: relative; display: flex; justify-content: center; flex-direction: column; padding: 10px; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); -webkit-box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); -moz-box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); border-radius: 5px; } .brand_logo_container { position: absolute; height: 170px; width: 170px; top: -75px; border-radius: 50%; background: #60a3bc; padding: 10px; text-align: center; } .brand_logo { height: 150px; width: 150px; border-radius: 50%; border: 2px solid white; } .form_container { margin-top: 100px; } .login_btn { width: 100%; background: #c0392b !important; color: white !important; } .login_btn:focus { box-shadow: none !important; outline: 0px !important; } .login_container { padding: 0 2rem; } .input-group-text { background: #c0392b !important; color: white !important; border: 0 !important; border-radius: 0.25rem 0 0 0.25rem !important; } .input_user, .input_pass:focus { box-shadow: none !important; outline: 0px !important; } .custom-checkbox .custom-control-input:checked~.custom-control-label::before { background-color: #c0392b !important; } </style> </body> </html>