Dalam bahagian sebelumnya dalam siri ini, kami melihat cara untuk mula menggunakan Flask Python dan MySQL dan melaksanakan bahagian pendaftaran pengguna aplikasi. Dalam tutorial ini, kami akan membawanya ke peringkat seterusnya dengan melaksanakan fungsi log masuk dan log keluar untuk aplikasi kami.
Mulakan dengan mengklonkan kod sumber tutorial sebelumnya daripada GitHub.
git clone https://github.com/tutsplus/create-a-web-app-from-scratch-using-python-flask-and-mysql/.git
Selepas mengklonkan kod sumber, navigasi ke direktori bahagian-1 dan mulakan pelayan.
python app.py
Tuding pelayar anda ke https://localhost:5000 dan aplikasi sepatutnya berjalan.
Navigasi ke FlaskApp/templates dan buat fail baharu bernama signin.html. Buka signin.html dan tambah kod HTML berikut:
<!DOCTYPE html> <html lang="en"> <head> <title>Python Flask Bucket List App - Sign In</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/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 tambah laluan baharu untuk skrin log masuk.
@app.route('/signin') def showSignin(): return render_template('signin.html')
Seterusnya, buka index.html dan signup.html dan tambah pautan href
untuk log masuk pada kedua-dua halaman: ”>/signin< /kod>. Simpan semua perubahan dan mulakan semula pelayan. <code class="inline">href
链接: /signin
。保存所有更改并重新启动服务器。
python app.py
将浏览器指向 http://localhost:5000 并单击登录链接,您应该能够看到登录页面。
现在,我们需要创建一个函数来验证用户登录。单击登录后,我们会将输入的电子邮件地址和密码发布到验证用户功能。
为了验证用户,我们需要一个 MySQL 存储过程。因此创建一个MySQL存储过程如图:
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 ;
我们将使用 sp_validateLogin
从 MySQL 数据库中获取基于 用户名
的用户详细信息。获得哈希密码后,我们将根据用户输入的密码对其进行验证。
创建一个方法来验证用户,我们将在用户提交表单时调用该方法:
@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))
如上面的代码所示,我们已将发布的电子邮件地址和密码读取到 _username
和 _password
中。现在我们将使用参数 _username
来调用 sp_validateLogin
过程。因此,在 validatelogin
方法内创建一个 MySQL 连接:
con = mysql.connect()
创建连接后,使用 con
连接创建 cursor
。
cursor = con.cursor()
使用游标,调用MySQL存储过程,如下所示:
cursor.callproc('sp_validateLogin',(_username,))
从游标中获取获取的记录,如下所示:
data = cursor.fetchall()
如果数据有一些记录,我们会将检索到的密码与用户输入的密码进行匹配。
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.')
如上面的代码所示,我们使用了一个名为 check_password_hash
的方法来检查返回的哈希密码是否与用户输入的密码匹配。如果一切顺利,我们会将用户重定向到 userHome.html。如果出现任何错误,我们将显示 error.html 以及错误消息。
这是完整的 validateLogin
代码:
@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()
在 templates 文件夹中创建一个名为 userhome.html 的页面,并添加以下 HTML 代码:
<!DOCTYPE html> <html lang="en"> <head> <title>Python Flask Bucket List App - Home</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/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>
此外,在 templates
文件夹中创建一个名为 error.html 的错误页面,并添加以下 HTML 代码:
<!DOCTYPE html> <html lang="en"> <head> <title>Error - Python Flask App</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/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>
在 error.html 中,我们有一个元素,如下所示:
<h1 class="text-center fw-bold display-5">{{error}}</h1>
变量的值可以从 render_template
函数传递,并且可以动态设置。
成功登录后,我们将用户重定向到用户主页,因此我们需要创建一个名为 /userHome
@app.route('/userHome') def userHome(): return render_template('userHome.html')
Log Masuk dan anda sepatutnya dapat melihat halaman log masuk.
Realisasikan log masuk
Kini, kita perlu mencipta fungsi untuk mengesahkan log masuk pengguna. Selepas mengklik
Log Masuk, kami akan menghantar alamat e-mel dan kata laluan yang dimasukkan ke fungsi Sahkan Pengguna.
from flask import session
sp_validateLogin
untuk mendapatkan butiran pengguna berdasarkan nama pengguna
daripada pangkalan data MySQL. Sebaik sahaja kami mempunyai kata laluan yang dicincang, kami mengesahkannya terhadap kata laluan yang dimasukkan oleh pengguna. 🎜
app.secret_key = 'why would I tell you my secret key?'
_username
dan _password
. Sekarang kami akan memanggil prosedur sp_validateLogin
dengan parameter _username
. Jadi, buat sambungan MySQL di dalam kaedah validatelogin
: 🎜
session['user'] = data[0][0]
con
untuk mencipta kursor
. 🎜
@app.route('/userhome') def userHome(): if session.get('user'): return render_template('userhome.html') else: return render_template('error.html',error = 'Unauthorized Access')
@app.route('/logout') def logout(): session.pop('user',None) return redirect('/')
check_password_hash
untuk menyemak sama ada kata laluan cincang yang dikembalikan sepadan dengan kata laluan yang dimasukkan oleh pengguna. Jika semuanya berjalan lancar, kami akan mengubah hala pengguna ke 🎜userHome.html🎜. Jika berlaku sebarang ralat, kami akan memaparkan 🎜error.html🎜 bersama dengan mesej ralat. 🎜
🎜Ini ialah kod validateLogin
yang lengkap: 🎜
rrreee
🎜Buat halaman bernama 🎜userhome.html🎜 dalam folder templat dan tambahkan kod HTML berikut: 🎜
rrreee
🎜Selain itu, buat halaman ralat bernama 🎜error.html🎜 dalam folder templates
dan tambahkan kod HTML berikut: 🎜
rrreee
🎜Dalam 🎜error.html🎜 kita mempunyai elemen yang kelihatan seperti ini: 🎜
rrreee
🎜Nilai pembolehubah boleh dihantar daripada fungsi render_template
dan boleh ditetapkan secara dinamik. 🎜
🎜Selepas log masuk berjaya, kami mengubah hala pengguna ke halaman utama pengguna, jadi kami perlu membuat laluan yang dipanggil /userHome
seperti yang ditunjukkan di bawah: 🎜
rrreee
🎜Simpan semua perubahan dan mulakan semula pelayan. Klik pautan 🎜Log Masuk🎜 pada halaman utama dan cuba log masuk dengan alamat e-mel dan kata laluan yang sah. Selepas pengesahan pengguna berjaya, anda sepatutnya melihat halaman seperti ini: 🎜
🎜🎜🎜
🎜Apabila pengesahan pengguna tidak berjaya, pengguna akan dialihkan ke halaman ralat seperti yang ditunjukkan di bawah: 🎜
🎜🎜🎜
🎜Di sini kami menggunakan halaman ralat yang berasingan untuk memaparkan ralat. Jika anda ingin menggunakan halaman yang sama untuk memaparkan mesej ralat itu juga tidak mengapa. 🎜
用户验证成功后,用户将被重定向到用户主页。但现在,即使是未经授权的用户也可以通过简单地浏览 URL http://localhost:5000/userhome 来查看主页。
为了限制未经授权的用户访问,我们将检查会话变量,并在用户成功登录时设置该变量。因此从 Flask 导入 session
:
from flask import session
我们还需要为会话设置一个密钥。因此,在 app.py
中,在应用程序初始化后,设置密钥,如下所示:
app.secret_key = 'why would I tell you my secret key?'
现在,在 validateLogin
方法中,在成功登录后将用户重定向到 /userhome
之前,设置 session
变量,如下所示:
session['user'] = data[0][0]
接下来,在 userhome
方法内,在渲染 userhome.html
之前检查会话变量。如果未找到会话变量,则重定向到错误页面。
@app.route('/userhome') def userHome(): if session.get('user'): return render_template('userhome.html') else: return render_template('error.html',error = 'Unauthorized Access')
保存所有更改并重新启动服务器。在不登录的情况下,尝试导航到 http://localhost:5000/userhome,由于您尚未登录,因此您应该被重定向到错误页面。
实现注销功能是最简单的。我们需要做的就是将会话变量 user
设置为 null 并将用户重定向到主页。
在app.py中,为 logout
创建一个新的路由和方法,如下所示:
@app.route('/logout') def logout(): session.pop('user',None) return redirect('/')
我们已经将注销按钮的 href 设置为 /logout
。因此,保存所有更改并重新启动服务器。在主页上,单击登录并尝试使用有效的电子邮件地址和密码登录。登录后,单击用户主页中的注销按钮,您应该会成功从应用程序注销。
在本教程的这一部分中,我们了解了如何实现用户登录和注销功能。我们还了解了如何限制对应用程序页面的未经授权的访问。在本教程的下一部分中,我们将实现登录用户在应用程序中添加和编辑博客文章的功能。
这篇文章已根据 Jacob Jackson 的贡献进行了更新。 Jacob 是一名 Web 开发人员、技术作家、自由职业者和开源贡献者。
Atas ialah kandungan terperinci Meneruskan perjalanan: Membina aplikasi web Python Flask dan MySQL dari awal - Bahagian 2. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!