Rumah  >  Artikel  >  hujung hadapan web  >  Meneruskan perjalanan: Membina aplikasi web Python Flask dan MySQL dari awal - Bahagian 2

Meneruskan perjalanan: Membina aplikasi web Python Flask dan MySQL dari awal - Bahagian 2

WBOY
WBOYasal
2023-09-02 09:25:041230semak imbas

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

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.

Buat antara muka log masuk

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>&copy; 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. Simpan semua perubahan dan mulakan semula pelayan. <code class="inline">href 链接: /signin。保存所有更改并重新启动服务器。

python app.py

将浏览器指向 http://localhost:5000 并单击登录链接,您应该能够看到登录页面。

继续旅程:从头开始构建 Python Flask 和 MySQL Web 应用程序 - 第 2 部分

实现登录

现在,我们需要创建一个函数来验证用户登录。单击登录后,我们会将输入的电子邮件地址和密码发布到验证用户功能。

创建存储过程

为了验证用户,我们需要一个 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>&copy; 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>&copy; 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')
    

Hala pelayar anda ke http://localhost:5000 dan klik pautan

Log Masuk dan anda sepatutnya dapat melihat halaman log masuk.

Teruskan perjalanan: Membina aplikasi web Python Flask dan MySQL dari awal - Bahagian 2

继续旅程:从头开始构建 Python Flask 和 MySQL Web 应用程序 - 第 2 部分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. 继续旅程:从头开始构建 Python Flask 和 MySQL Web 应用程序 - 第 2 部分

Buat prosedur tersimpan

Untuk mengesahkan pengguna, kami memerlukan prosedur tersimpan MySQL. Jadi buat prosedur tersimpan MySQL seperti yang ditunjukkan:

from flask import session

Kami akan menggunakan 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. 🎜

Sahkan kaedah pengguna

🎜Buat kaedah untuk mengesahkan pengguna yang akan kami panggil apabila pengguna menyerahkan borang: 🎜
app.secret_key = 'why would I tell you my secret key?'
🎜Seperti yang ditunjukkan dalam kod di atas, kami telah membaca alamat e-mel dan kata laluan yang diterbitkan ke dalam _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]
🎜Selepas membuat sambungan, gunakan sambungan 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')
🎜Gunakan kursor untuk memanggil prosedur tersimpan MySQL seperti berikut: 🎜
@app.route('/logout')
def logout():
    session.pop('user',None)
    return redirect('/')
🎜Dapatkan rekod yang diambil daripada kursor seperti berikut: 🎜 rrreee 🎜Jika data mempunyai beberapa rekod, kami akan memadankan kata laluan yang diambil dengan kata laluan yang dimasukkan oleh pengguna. 🎜 rrreee 🎜Seperti yang ditunjukkan dalam kod di atas, kami menggunakan kaedah yang dipanggil 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,由于您尚未登录,因此您应该被重定向到错误页面。

继续旅程:从头开始构建 Python Flask 和 MySQL Web 应用程序 - 第 2 部分

实现注销

实现注销功能是最简单的。我们需要做的就是将会话变量 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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn