sql >> Databasteknik >  >> RDS >> Mysql

Skapa en webbapp från grunden med Python Flask och MySQL:Del 2

I den tidigare delen av den här serien såg vi hur man kommer igång med Python Flask och MySQL och implementerade användarregistreringsdelen av vår applikation. I den här handledningen tar vi det här till nästa nivå genom att implementera inloggnings- och utloggningsfunktionen för vår applikation.

Komma igång

Klona först källkoden för den föregående handledningen från GitHub.

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

När källkoden har klonats, navigera till del-1 katalogen och starta servern.

python app.py

Peka med din webbläsare till https://localhost:5000 och du bör ha programmet igång.

Skapa inloggningsgränssnittet

Navigera till FlaskApp/mallar och skapa en ny fil som heter signin.html . Öppna signin.html och lägg till följande HTML-kod:

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

Öppna app.py och lägg till en ny rutt för inloggningsgränssnittet.

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

Öppna sedan index.html och signup.html , och lägg till href länk för inloggning på båda sidorna som /signin . Spara alla ändringar och starta om servern.

python app.py

Peka med din webbläsare till http://localhost:5000 och klicka på Logga in länk, och du bör kunna se inloggningssidan.

Implementera inloggning

Nu måste vi skapa en funktion för att validera användarinloggningen. När du klickar på Logga in , skickar vi den angivna e-postadressen och lösenordet till funktionen för att verifiera användaren.

Skapa en lagrad procedur

För att validera en användare behöver vi en lagrad MySQL-procedur. Så skapa en MySQL-lagrad procedur enligt bilden:

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 ;

Vi får användarinformationen baserat på username från MySQL-databasen med sp_validateLogin . När vi har det hashade lösenordet validerar vi det mot lösenordet som användaren angett.

Verifiera användarmetoden

Skapa en metod för att validera användaren som vi anropar när användaren skickar formuläret:

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

Som framgår av koden ovan har vi läst den angivna e-postadressen och lösenordet till _username och _password . Nu ska vi anropa sp_validateLogin procedur med parametern _username . Så skapa en MySQL-anslutning i validatelogin metod:

con = mysql.connect()

När anslutningen har skapats skapar du en cursor med hjälp av con anslutning.

cursor = con.cursor()

Använd markören för att anropa den lagrade MySQL-proceduren som visas:

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

Hämta de hämtade posterna från markören som visas:

data = cursor.fetchall()

Om uppgifterna har några uppgifter kommer vi att matcha det hämtade lösenordet mot lösenordet som angetts av användaren.

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

Som framgår av koden ovan har vi använt en metod som heter check_password_hash för att kontrollera om det returnerade hash-lösenordet matchar lösenordet som användaren angett. Om allt är bra omdirigerar vi användaren till userHome.html . Och om det finns något fel visar vi error.html med felmeddelandet.

Här är den fullständiga validateLogin kod:

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

Skapa en sida som heter userhome.html i mallmappen och lägg till följande HTML-kod:

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

Skapa även en felsida som heter error.html i templates mapp och lägg till följande HTML-kod:

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

Inuti error.html , vi har ett element som visas:

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

Värdet för variabeln kan skickas från render_template funktion och kan ställas in dynamiskt.

Vid lyckad inloggning omdirigerar vi användaren till användarens hemsida, så vi måste skapa en rutt som heter /userHome som visas:

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

Spara alla ändringar och starta om servern. Klicka på Logga in länken på startsidan och försök logga in med en giltig e-postadress och lösenord. Vid framgångsrik användarvalidering bör du ha en sida som visas nedan:

Vid en misslyckad användarvalidering omdirigeras användaren till en felsida som visas nedan:

Här har vi använt en separat felsida för att visa felet. Det är också bra om du vill använda samma sida för att visa felmeddelandet.

Begränsa obehörig åtkomst till användarens hemsida

Vid framgångsrik användarvalidering omdirigeras en användare till användarens hemsida. Men just nu kan även en obehörig användare se hemsidan genom att helt enkelt bläddra i URL:en http://localhost:5000/userhome.

För att begränsa obehörig användaråtkomst söker vi efter en sessionsvariabel som vi ställer in vid lyckad användarinloggning. Så importera session från kolven:

from flask import session

Vi måste också ställa in en hemlig nyckel för sessionen. Så i app.py , efter att appen har initierats, ställ in den hemliga nyckeln som visas :

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

Nu, inuti validateLogin metod innan användaren omdirigeras till /userhome vid lyckad inloggning ställer du in session variabel som visas:

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

Därefter inuti userhome metod, kontrollera efter sessionsvariabeln innan du renderar userhome.html . Om sessionsvariabeln inte hittas, omdirigera till felsidan.

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

Spara alla ändringar och starta om servern. Utan att logga in, försök att navigera till http://localhost:5000/userhome och eftersom du inte har loggat in ännu bör du omdirigeras till felsidan.

Implementera utloggning

Att implementera utloggningsfunktionen är det enklaste. Allt vi behöver göra är att göra sessionsvariabeln user null och omdirigera användaren till huvudsidan.

Inuti app.py , skapa en ny rutt och metod för logout som visas:

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

Vi har redan ställt in href för utloggningsknappen till /logout . Så spara alla ändringar och starta om servern. På startsidan klickar du på Logga in och försök logga in med en giltig e-postadress och lösenord. När du har loggat in klickar du på Logga ut knappen i användarhemmet och du bör loggas ut från applikationen.


  1. Rensa Hibernate 2:a nivås cache efter manuell DB-uppdatering

  2. Autogenererar svarsfil

  3. JSON_ARRAYAGG() – Skapa en JSON-array från raderna i en fråga i MySQL

  4. Varför respekterar inte PL/SQL privilegier som ges av roller?