Python >> Python Tutorial >  >> Python Tag >> MySQL

Erstellen einer Web-App von Grund auf neu mit Python Flask und MySQL:Teil 2

Im vorherigen Teil dieser Serie haben wir gesehen, wie Sie mit Python Flask und MySQL beginnen und den Benutzerregistrierungsteil unserer Anwendung implementiert haben. In diesem Tutorial bringen wir dies auf die nächste Ebene, indem wir die Anmelde- und Abmeldefunktion für unsere Anwendung implementieren.

Erste Schritte

Klonen Sie zuerst den Quellcode des vorherigen Tutorials von GitHub.

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

Navigieren Sie nach dem Klonen des Quellcodes zu Teil-1 Verzeichnis und starten Sie den Server.

python app.py

Richten Sie Ihren Browser auf https://localhost:5000 und die Anwendung sollte laufen.

Erstellen der Anmeldeoberfläche

Navigieren Sie zu FlaskApp/Vorlagen und erstellen Sie eine neue Datei namens signin.html . Öffnen Sie signin.html und fügen Sie den folgenden HTML-Code hinzu:

<!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>&copy; Company 2022</p>
				        
			</footer>

			    
		</div>

	</body>
</html>

Öffnen Sie app.py und fügen Sie eine neue Route für die Anmeldeschnittstelle hinzu.

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

Als nächstes öffnen Sie index.html und signup.html , und fügen Sie href hinzu Link für die Anmeldung auf beiden Seiten als /signin . Speichern Sie alle Änderungen und starten Sie den Server neu.

python app.py

Richten Sie Ihren Browser auf http://localhost:5000 und klicken Sie auf Anmelden Link, und Sie sollten die Anmeldeseite sehen können.

Anmeldung implementieren

Jetzt müssen wir eine Funktion erstellen, um die Benutzeranmeldung zu validieren. Beim Klicken auf Anmelden , werden wir die eingegebene E-Mail-Adresse und das Passwort an die Benutzervalidierungsfunktion senden.

Erstellen einer gespeicherten Prozedur

Um einen Benutzer zu validieren, benötigen wir eine gespeicherte MySQL-Prozedur. Erstellen Sie also eine gespeicherte MySQL-Prozedur wie gezeigt:

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 ;

Wir erhalten die Benutzerdetails basierend auf dem username aus der MySQL-Datenbank mit sp_validateLogin . Sobald wir das gehashte Passwort haben, validieren wir es mit dem vom Benutzer eingegebenen Passwort.

Validieren Sie die Benutzermethode

Erstellen Sie eine Methode zur Validierung des Benutzers, die aufgerufen wird, wenn der Benutzer das Formular absendet:

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

Wie im obigen Code zu sehen ist, haben wir die gepostete E-Mail-Adresse und das Passwort in _username eingelesen und _password . Jetzt rufen wir sp_validateLogin auf Prozedur mit dem Parameter _username . Erstellen Sie also eine MySQL-Verbindung innerhalb des validatelogin Methode:

con = mysql.connect()

Nachdem die Verbindung erstellt wurde, erstellen Sie einen cursor mit dem con Verbindung.

cursor = con.cursor()

Rufen Sie mit dem Cursor die gespeicherte MySQL-Prozedur wie gezeigt auf:

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

Holen Sie sich die abgerufenen Datensätze vom Cursor wie gezeigt:

data = cursor.fetchall()

Wenn die Daten einige Datensätze enthalten, gleichen wir das abgerufene Passwort mit dem vom Benutzer eingegebenen Passwort ab.

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

Wie im obigen Code zu sehen ist, haben wir eine Methode namens check_password_hash verwendet um zu überprüfen, ob das zurückgegebene Hash-Passwort mit dem vom Benutzer eingegebenen Passwort übereinstimmt. Wenn alles in Ordnung ist, leiten wir den Benutzer zu userHome.html weiter . Und wenn es einen Fehler gibt, zeigen wir error.html an mit der Fehlermeldung.

Hier ist der vollständige validateLogin Code:

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

Erstellen Sie eine Seite namens userhome.html im Vorlagenordner und fügen Sie den folgenden HTML-Code hinzu:

<!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>&copy; Company 2022</p>
				        
			</footer>

			    
		</div>
	</body>
</html>

Erstellen Sie außerdem eine Fehlerseite namens error.html in den templates Ordner und fügen Sie den folgenden HTML-Code hinzu:

<!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>&copy; Company 2022</p>
				        
			</footer>

			    
		</div>
	</body>
</html>

Innerhalb von error.html , haben wir ein Element wie gezeigt:

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

Der Wert für die Variable kann aus dem render_template übergeben werden Funktion und kann dynamisch gesetzt werden.

Bei erfolgreicher Anmeldung leiten wir den Benutzer zur Benutzerhomepage weiter, daher müssen wir eine Route mit dem Namen /userHome erstellen wie gezeigt:

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

Speichern Sie alle Änderungen und starten Sie den Server neu. Klicken Sie auf Anmelden Link auf der Startseite und versuchen Sie, sich mit einer gültigen E-Mail-Adresse und einem gültigen Passwort anzumelden. Bei erfolgreicher Benutzervalidierung sollten Sie eine Seite wie unten gezeigt haben:

Bei einer nicht erfolgreichen Benutzervalidierung wird der Benutzer wie unten gezeigt auf eine Fehlerseite umgeleitet:

Hier haben wir eine separate Fehlerseite verwendet, um den Fehler anzuzeigen. Es ist auch in Ordnung, wenn Sie dieselbe Seite verwenden möchten, um die Fehlermeldung anzuzeigen.

Einschränken des unbefugten Zugriffs auf die Benutzer-Homepage

Bei erfolgreicher Benutzervalidierung wird ein Benutzer auf die Benutzerhomepage umgeleitet. Aber im Moment kann sogar ein unbefugter Benutzer die Homepage anzeigen, indem er einfach die URL http://localhost:5000/userhome.

durchsucht

Um den unbefugten Benutzerzugriff einzuschränken, suchen wir nach einer Sitzungsvariablen, die wir bei erfolgreicher Benutzeranmeldung festlegen. Importieren Sie also session aus Flasche:

from flask import session

Wir müssen auch einen geheimen Schlüssel für die Sitzung festlegen. Also in app.py , nachdem die App initialisiert wurde, legen Sie den geheimen Schlüssel wie gezeigt fest:

app.secret_key = 'why would I tell you my secret key?'

Jetzt innerhalb des validateLogin -Methode, bevor der Benutzer zu /userhome umgeleitet wird Legen Sie bei erfolgreicher Anmeldung die session fest Variable wie gezeigt:

session['user'] = data[0][0]

Als nächstes im userhome -Methode, überprüfen Sie die Sitzungsvariable, bevor Sie userhome.html rendern . Wenn die Sitzungsvariable nicht gefunden wird, leiten Sie zur Fehlerseite weiter.

@app.route('/userhome')
def userHome():
    if session.get('user'):
        return render_template('userhome.html')
    else:
        return render_template('error.html',error = 'Unauthorized Access')

Speichern Sie alle Änderungen und starten Sie den Server neu. Versuchen Sie, ohne sich anzumelden, zu http://localhost:5000/userhome zu navigieren. Da Sie sich noch nicht angemeldet haben, sollten Sie zur Fehlerseite weitergeleitet werden.

Abmelden implementieren

Die Implementierung der Abmeldefunktion ist am einfachsten. Alles, was wir tun müssen, ist die Sitzungsvariable user zu erstellen null und den Benutzer auf die Hauptseite umleiten.

Innerhalb von app.py , erstellen Sie eine neue Route und Methode für logout wie gezeigt:

@app.route('/logout')
def logout():
    session.pop('user',None)
    return redirect('/')

Wir haben das href für den Logout-Button bereits auf /logout gesetzt . Speichern Sie also alle Änderungen und starten Sie den Server neu. Klicken Sie auf der Startseite auf Anmelden und versuchen Sie, sich mit einer gültigen E-Mail-Adresse und einem gültigen Passwort anzumelden. Nachdem Sie sich angemeldet haben, klicken Sie auf Abmelden Schaltfläche im Benutzer-Home und Sie sollten erfolgreich von der Anwendung abgemeldet werden.

Schlussfolgerung

In diesem Teil des Tutorials haben wir gesehen, wie die Benutzer-Login- und Logout-Funktionalität implementiert wird. Wir haben auch gesehen, wie man den unbefugten Zugriff auf Anwendungsseiten einschränkt. Im nächsten Teil dieses Tutorials implementieren wir die Funktionalität für den angemeldeten Benutzer, einen Blogbeitrag in der Anwendung hinzuzufügen und zu bearbeiten.

Dieser Beitrag wurde mit Beiträgen von Jacob Jackson aktualisiert. Jacob ist Webentwickler, technischer Redakteur, Freiberufler und Open-Source-Mitarbeiter.