Maison  >  Article  >  interface Web  >  Poursuivre le voyage : créer une application Web Python Flask et MySQL à partir de zéro - Partie 2

Poursuivre le voyage : créer une application Web Python Flask et MySQL à partir de zéro - Partie 2

WBOY
WBOYoriginal
2023-09-02 09:25:041230parcourir

Dans la partie précédente de cette série, nous avons vu comment démarrer avec Python Flask et MySQL et implémenter la partie enregistrement des utilisateurs de l'application. Dans ce didacticiel, nous passerons au niveau supérieur en implémentant la fonctionnalité de connexion et de déconnexion pour notre application.

Commencer

Commencez par cloner le code source du tutoriel précédent depuis GitHub.

git clone https://github.com/tutsplus/create-a-web-app-from-scratch-using-python-flask-and-mysql/.git

Après avoir cloné le code source, accédez au répertoire part-1 et démarrez le serveur.

python app.py

Pointez votre navigateur sur https://localhost:5000 et l'application devrait être en cours d'exécution.

Créer une interface de connexion

Accédez à FlaskApp/templates et créez un nouveau fichier appelé signin.html. Ouvrez signin.html et ajoutez le code HTML suivant :

<!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>

Ouvrez app.py et ajoutez un nouvel itinéraire pour l'écran de connexion.

@app.route('/signin')
def showSignin():
    return render_template('signin.html')

Ensuite, ouvrez index.html et signup.html et ajoutez href 链接: /signin pour vous connecter sur les deux pages. Enregistrez toutes les modifications et redémarrez le serveur.

python app.py

Pointez votre navigateur sur http://localhost:5000 et cliquez sur le lien Connexion et vous devriez pouvoir voir la page de connexion.

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

Réaliser la connexion

Maintenant, nous devons créer une fonction pour authentifier la connexion de l'utilisateur. Après avoir cliqué sur Connexion, nous publierons l'adresse e-mail et le mot de passe saisis dans la fonction Vérifier l'utilisateur.

Créer des procédures stockées

Pour authentifier l'utilisateur, nous avons besoin d'une procédure stockée MySQL. Créez donc une procédure stockée MySQL comme indiqué :

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 ;

Nous utiliserons les détails de l'utilisateur de sp_validateLogin 从 MySQL 数据库中获取基于 用户名. Une fois que nous avons le mot de passe haché, nous le vérifions par rapport au mot de passe saisi par l'utilisateur.

Vérifier la méthode utilisateur

Créez une méthode pour authentifier l'utilisateur que nous appellerons lorsque l'utilisateur soumettra le formulaire :

@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))

Comme le montre le code ci-dessus, nous avons lu l'adresse e-mail et le mot de passe publiés dans la _username_password 中。现在我们将使用参数 _username 来调用 sp_validateLogin 过程。因此,在 validatelogin méthode pour créer une connexion MySQL :

con = mysql.connect()

Après avoir créé la connexion, utilisez con 连接创建 cursor.

cursor = con.cursor()

Utilisez un curseur pour appeler la procédure stockée MySQL comme suit :

cursor.callproc('sp_validateLogin',(_username,))

Récupérez les enregistrements récupérés à partir du curseur comme suit :

data = cursor.fetchall()

Si les données contiennent des enregistrements, nous ferons correspondre le mot de passe récupéré avec le mot de passe saisi par l'utilisateur.

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.')

Comme le montre le code ci-dessus, nous utilisons une méthode appelée check_password_hash pour vérifier si le mot de passe haché renvoyé correspond au mot de passe saisi par l'utilisateur. Si tout se passe bien, nous redirigerons l'utilisateur vers userHome.html. Si des erreurs se produisent, nous afficherons error.html avec le message d'erreur.

Voici le validateLogincode complet :

@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()

Créez une page appelée userhome.html dans le dossier des modèles et ajoutez le code HTML suivant :

<!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>

Créez également une page d'erreur appelée templateserror.html dans le dossier et ajoutez le code HTML suivant :

<!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>

Dans error.html nous avons un élément qui ressemble à ceci :

<h1 class="text-center fw-bold display-5">{{error}}</h1>

Les valeurs des variables peuvent être transmises à partir des fonctions render_template et peuvent être définies dynamiquement.

Après une connexion réussie, nous redirigeons l'utilisateur vers la page d'accueil de l'utilisateur, nous devons donc créer un itinéraire nommé /userHome comme indiqué ci-dessous :

@app.route('/userHome')
def userHome():
    return render_template('userHome.html')
    

Enregistrez toutes les modifications et redémarrez le serveur. Cliquez sur le lien Connexion sur la page d'accueil et essayez de vous connecter avec une adresse e-mail et un mot de passe valides. Après une vérification réussie de l'utilisateur, vous devriez voir une page comme celle-ci :

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

Lorsque la vérification de l'utilisateur échoue, l'utilisateur sera redirigé vers une page d'erreur comme indiqué ci-dessous :

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

Ici, nous utilisons une page d'erreur distincte pour afficher les erreurs. Si vous souhaitez utiliser la même page pour afficher les messages d'erreur, c'est bien aussi.

限制未经授权访问用户主页

用户验证成功后,用户将被重定向到用户主页。但现在,即使是未经授权的用户也可以通过简单地浏览 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 开发人员、技术作家、自由职业者和开源贡献者。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn