Di bagian sebelumnya dari seri ini, kita melihat bagaimana memulai dengan Python Flask dan MySQL dan mengimplementasikan bagian pendaftaran pengguna dari aplikasi kita. Dalam tutorial ini, kita akan membawanya ke tingkat berikutnya dengan menerapkan fungsi masuk dan keluar untuk aplikasi kita.
Memulai
Pertama clone kode sumber dari tutorial sebelumnya dari GitHub.
git clone https://github.com/tutsplus/create-a-web-app-from-scratch-using-python-flask-and-mysql/.git
Setelah kode sumber dikloning, navigasikan ke part-1 direktori dan mulai server.
python app.py
Arahkan browser Anda ke https://localhost:5000 dan Anda akan menjalankan aplikasi tersebut.
Membuat Antarmuka Masuk
Navigasikan ke FlaskApp/template dan buat file baru bernama signin.html . Buka signin.html dan tambahkan kode HTML berikut:
<!DOCTYPE html> <html lang="en"> <head> <title>Python Flask Bucket List App - Sign In</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" /> <link href="../static/signup.css" rel="stylesheet" /> </head> <body> <div class="container"> <div class="header"> <nav class="border-bottom flex-wrap mb-4 py-3 d-flex justify-content-center" > <a href="/" class="text-dark text-decoration-none mb-3 mb-md-0 d-flex align-items-center me-md-auto" > <span class="fs-4">Python Flask App</span> </a> <ul class="nav nav-pills"> <li class="nav-item"> <a href="/" class="nav-link">Home</a> </li> <li class="nav-item"> <a href="/signup" class="nav-link">Signup</a> </li> <li class="nav-item"> <a href="/signin" class="nav-link active" aria-current="page" >Sign In</a > </li> </ul> </nav> </div> <div class="bg-light rounded-3 mb-4 p-5"> <div class="container-fluid py-5"> <h1 class="text-center fw-bold display-5">Bucket List App</h1> <form class="form-signin" action="/api/validateLogin" method="post"> <label for="inputEmail" class="sr-only">Email address</label> <input type="email" name="inputEmail" id="inputEmail" class="form-control" placeholder="Email address" required autofocus> <label for="inputPassword" class="sr-only">Password</label> <input type="password" name="inputPassword" id="inputPassword" class="form-control" placeholder="Password" required> <button id="btnSignIn" class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> </form> </div> <footer class="footer"> <p>© Company 2022</p> </footer> </div> </body> </html>
Buka app.py dan tambahkan rute baru untuk antarmuka masuk.
@app.route('/signin') def showSignin(): return render_template('signin.html')
Selanjutnya, buka index.html dan signup.html , dan tambahkan href
tautan untuk masuk di kedua halaman sebagai /signin
. Simpan semua perubahan dan mulai ulang server.
python app.py
Arahkan browser Anda ke http://localhost:5000 dan klik tombol Masuk link, dan Anda seharusnya dapat melihat halaman login.
Menerapkan Masuk
Sekarang, kita perlu membuat fungsi untuk memvalidasi login pengguna. Saat mengeklik Masuk , kami akan mengirimkan alamat email dan sandi yang dimasukkan ke fungsi validasi pengguna.
Membuat Prosedur Tersimpan
Untuk memvalidasi pengguna, kita memerlukan prosedur tersimpan MySQL. Jadi buat prosedur tersimpan MySQL seperti yang ditunjukkan:
DELIMITER $$ CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_validateLogin`( IN p_username VARCHAR(20) ) BEGIN select * from tbl_user where user_username = p_username; END$$ DELIMITER ;
Kami akan mendapatkan detail pengguna berdasarkan username
dari database MySQL menggunakan sp_validateLogin
. Setelah kami memiliki kata sandi yang di-hash, kami akan memvalidasinya dengan kata sandi yang dimasukkan oleh pengguna.
Validasi Metode Pengguna
Buat metode untuk memvalidasi pengguna yang akan kita panggil saat pengguna mengirimkan formulir:
@app.route('/api/validateLogin',methods=['POST']) def validateLogin(): try: _username = request.form['inputEmail'] _password = request.form['inputPassword'] except Exception as e: return render_template('error.html',error = str(e))
Seperti yang terlihat pada kode di atas, kami telah membaca alamat email dan kata sandi yang diposting ke _username
dan _password
. Sekarang kita akan memanggil sp_validateLogin
prosedur dengan parameter _username
. Jadi buat koneksi MySQL di dalam validatelogin
metode:
con = mysql.connect()
Setelah koneksi dibuat, buat cursor
menggunakan con
koneksi.
cursor = con.cursor()
Menggunakan kursor, panggil prosedur tersimpan MySQL seperti yang ditunjukkan:
cursor.callproc('sp_validateLogin',(_username,))
Dapatkan catatan yang diambil dari kursor seperti yang ditunjukkan:
data = cursor.fetchall()
Jika data memiliki beberapa catatan, kami akan mencocokkan kata sandi yang diambil dengan kata sandi yang dimasukkan oleh pengguna.
if len(data) > 0: if check_password_hash(str(data[0][3]),_password): return redirect('/userhome') else: return render_template('error.html',error = 'Wrong Email address or Password.') else: return render_template('error.html',error = 'Wrong Email address or Password.')
Seperti yang terlihat pada kode di atas, kami telah menggunakan metode yang disebut check_password_hash
untuk memeriksa apakah kata sandi hash yang dikembalikan cocok dengan kata sandi yang dimasukkan oleh pengguna. Jika semuanya baik-baik saja, kami akan mengarahkan pengguna ke userHome.html . Dan jika ada kesalahan, kami akan menampilkan error.html dengan pesan kesalahan.
Berikut validateLogin
lengkapnya kode:
@app.route('/api/validateLogin',methods=['POST']) def validateLogin(): try: _username = request.form['inputEmail'] _password = request.form['inputPassword'] # connect to mysql con = mysql.connect() cursor = con.cursor() cursor.callproc('sp_validateLogin',(_username,)) data = cursor.fetchall() if len(data) > 0: if check_password_hash(str(data[0][3]),_password): session['user'] = data[0][0] return redirect('/userHome') else: return render_template('error.html',error = 'Wrong Email address or Password') else: return render_template('error.html',error = 'Wrong Email address or Password') except Exception as e: return render_template('error.html',error = str(e)) finally: cursor.close() con.close()
Buat laman bernama userhome.html di dalam folder templates dan tambahkan kode HTML berikut:
<!DOCTYPE html> <html lang="en"> <head> <title>Python Flask Bucket List App - Home</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" /> </head> <body> <div class="container"> <div class="header"> <nav class="border-bottom flex-wrap mb-4 py-3 d-flex justify-content-center" > <a href="/" class="text-dark text-decoration-none mb-3 mb-md-0 d-flex align-items-center me-md-auto" > <span class="fs-4">Python Flask App</span> </a> <ul class="nav nav-pills"> <li class="nav-item"> <a href="/userhome" class="nav-link">Home</a> </li> <li class="nav-item"> <a href="/logout" class="nav-link active">Logout</a> </li> </ul> </nav> </div> <div class="bg-light rounded-3 mb-4 p-5"> <div class="container-fluid py-5"> <h1 class="text-center fw-bold display-5">Welcome Home!</h1> </div> </div> <footer class="footer"> <p>© Company 2022</p> </footer> </div> </body> </html>
Juga, buat laman kesalahan bernama error.html di templates
folder dan tambahkan kode HTML berikut:
<!DOCTYPE html> <html lang="en"> <head> <title>Error - Python Flask App</title> <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" /> </head> <body> <div class="container"> <div class="header"> <nav class="border-bottom flex-wrap mb-4 py-3 d-flex justify-content-center" > <a href="/" class="text-dark text-decoration-none mb-3 mb-md-0 d-flex align-items-center me-md-auto" > <span class="fs-4">Python Flask App</span> </a> <ul class="nav nav-pills"> <li class="nav-item"> <a href="/" class="nav-link">Home</a> </li> <li class="nav-item"> <a href="/signup" class="nav-link">Signup</a> </li> <li class="nav-item"> <a href="/signin" class="nav-link">Sign In</a> </li> </ul> </nav> </div> <div class="bg-light rounded-3 mb-4 p-5"> <div class="container-fluid py-5"> <h1 class="text-center fw-bold display-5">{{error}}</h1> </div> </div> <footer class="footer"> <p>© Company 2022</p> </footer> </div> </body> </html>
Di dalam error.html , kami memiliki elemen seperti yang ditunjukkan:
<h1 class="text-center fw-bold display-5">{{error}}</h1>
Nilai untuk variabel dapat diteruskan dari render_template
fungsi dan dapat diatur secara dinamis.
Saat berhasil masuk, kami mengarahkan pengguna ke halaman beranda pengguna, jadi kami perlu membuat rute yang disebut /userHome
seperti yang ditunjukkan:
@app.route('/userHome') def userHome(): return render_template('userHome.html')
Simpan semua perubahan dan mulai ulang server. Klik tombol Masuk di halaman beranda dan coba masuk menggunakan alamat email dan kata sandi yang valid. Pada validasi pengguna yang berhasil, Anda akan memiliki halaman seperti yang ditunjukkan di bawah ini:
Pada validasi pengguna yang gagal, pengguna akan diarahkan ke halaman kesalahan seperti yang ditunjukkan di bawah ini:
Di sini kami telah menggunakan halaman kesalahan terpisah untuk menampilkan kesalahan. Tidak apa-apa jika Anda ingin menggunakan halaman yang sama untuk menampilkan pesan kesalahan.
Membatasi Akses Tidak Sah ke Halaman Beranda Pengguna
Pada validasi pengguna yang berhasil, pengguna diarahkan ke halaman beranda pengguna. Tetapi sekarang bahkan pengguna yang tidak berwenang dapat melihat halaman beranda hanya dengan menjelajahi URL http://localhost:5000/userhome.
Untuk membatasi akses pengguna yang tidak sah, kami akan memeriksa variabel sesi yang akan kami atur pada login pengguna yang berhasil. Jadi impor session
dari labu:
from flask import session
Kita juga perlu mengatur kunci rahasia untuk sesi tersebut. Jadi di app.py
, setelah aplikasi diinisialisasi, atur kunci rahasia seperti yang ditunjukkan :
app.secret_key = 'why would I tell you my secret key?'
Sekarang, di dalam validateLogin
metode, sebelum mengarahkan pengguna ke /userhome
saat berhasil masuk, setel session
variabel seperti yang ditunjukkan:
session['user'] = data[0][0]
Selanjutnya, di dalam userhome
metode, periksa variabel sesi sebelum merender userhome.html
. Jika variabel sesi tidak ditemukan, arahkan ulang ke halaman kesalahan.
@app.route('/userhome') def userHome(): if session.get('user'): return render_template('userhome.html') else: return render_template('error.html',error = 'Unauthorized Access')
Simpan semua perubahan dan mulai ulang server. Tanpa masuk, coba navigasikan ke http://localhost:5000/userhome dan karena Anda belum masuk, Anda akan diarahkan ke halaman kesalahan.
Menerapkan Logout
Menerapkan fungsi logout adalah yang paling sederhana. Yang perlu kita lakukan adalah membuat variabel sesi user
null dan mengarahkan pengguna ke halaman utama.
Di dalam app.py , buat rute dan metode baru untuk logout
seperti yang ditunjukkan:
@app.route('/logout') def logout(): session.pop('user',None) return redirect('/')
Kami telah menyetel href untuk tombol keluar ke /logout
. Jadi simpan semua perubahan dan mulai ulang server. Dari beranda, klik Masuk dan coba masuk menggunakan alamat email dan kata sandi yang valid. Setelah Anda masuk, klik Keluar tombol di beranda pengguna dan Anda harus berhasil keluar dari aplikasi.