Mysql
 sql >> Database >  >> RDS >> Mysql

Creazione di un'app Web da zero utilizzando Python Flask e MySQL:parte 2

Nella parte precedente di questa serie, abbiamo visto come iniziare con Python Flask e MySQL e implementato la parte relativa alla registrazione degli utenti della nostra applicazione. In questo tutorial, porteremo questo al livello successivo implementando la funzionalità di accesso e disconnessione per la nostra applicazione.

Per iniziare

Prima clona il codice sorgente del tutorial precedente da GitHub.

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

Una volta clonato il codice sorgente, vai alla parte-1 directory e avvia il server.

python app.py

Punta il tuo browser su https://localhost:5000 e dovresti avere l'applicazione in esecuzione.

Creazione dell'interfaccia di accesso

Vai a FlaskApp/templates e crea un nuovo file chiamato signin.html . Apri signin.html e aggiungi il seguente codice HTML:

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

Apri app.py e aggiungi un nuovo percorso per l'interfaccia di accesso.

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

Quindi, apri index.html e signup.html e aggiungi il href link per l'accesso su entrambe le pagine come /signin . Salva tutte le modifiche e riavvia il server.

python app.py

Punta il browser su http://localhost:5000 e fai clic su Accedi link e dovresti essere in grado di vedere la pagina di accesso.

Implementazione dell'accesso

Ora, dobbiamo creare una funzione per convalidare l'accesso dell'utente. Facendo clic su Accedi , pubblicheremo l'indirizzo email e la password inseriti nella funzione di convalida utente.

Creazione di una stored procedure

Per convalidare un utente, avremo bisogno di una stored procedure MySQL. Quindi crea una stored procedure MySQL come mostrato:

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 ;

Otterremo i dettagli dell'utente in base al username dal database MySQL utilizzando sp_validateLogin . Una volta ottenuta la password con hash, la convalideremo rispetto alla password inserita dall'utente.

Convalida il metodo utente

Crea un metodo per convalidare l'utente che chiameremo quando l'utente invia il modulo:

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

Come visto nel codice sopra, abbiamo letto l'indirizzo email e la password pubblicati in _username e _password . Ora chiameremo sp_validateLogin procedura con il parametro _username . Quindi crea una connessione MySQL all'interno di validatelogin metodo:

con = mysql.connect()

Una volta creata la connessione, crea un cursor usando il con connessione.

cursor = con.cursor()

Usando il cursore, chiama la stored procedure MySQL come mostrato:

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

Ottieni i record recuperati dal cursore come mostrato:

data = cursor.fetchall()

Se i dati hanno dei record, abbineremo la password recuperata con la password inserita dall'utente.

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

Come visto nel codice sopra, abbiamo usato un metodo chiamato check_password_hash per verificare se la password hash restituita corrisponde alla password immessa dall'utente. Se tutto va bene, reindirizzeremo l'utente a userHome.html . E se c'è qualche errore, visualizzeremo error.html con il messaggio di errore.

Ecco il validateLogin completo codice:

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

Crea una pagina chiamata userhome.html all'interno della cartella dei modelli e aggiungi il seguente codice HTML:

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

Inoltre, crea una pagina di errore chiamata error.html nei templates cartella e aggiungi il seguente codice HTML:

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

Dentro error.html , abbiamo un elemento come mostrato:

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

Il valore per la variabile può essere passato da render_template funzione e può essere impostato dinamicamente.

Dopo l'accesso, stiamo reindirizzando l'utente alla home page dell'utente, quindi dobbiamo creare un percorso chiamato /userHome come mostrato:

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

Salva tutte le modifiche e riavvia il server. Fai clic su Accedi link nella home page e prova ad accedere utilizzando un indirizzo email e una password validi. Dopo la convalida dell'utente, dovresti avere una pagina come mostrato di seguito:

In caso di convalida utente non riuscita, l'utente verrà reindirizzato a una pagina di errore come mostrato di seguito:

Qui abbiamo utilizzato una pagina di errore separata per visualizzare l'errore. Va bene anche se vuoi usare la stessa pagina per visualizzare il messaggio di errore.

Limitazione dell'accesso non autorizzato alla home page dell'utente

Dopo la convalida dell'utente, un utente viene reindirizzato alla home page dell'utente. Ma in questo momento anche un utente non autorizzato può visualizzare la home page semplicemente sfogliando l'URL http://localhost:5000/userhome.

Per limitare l'accesso di utenti non autorizzati, verificheremo una variabile di sessione che imposteremo in caso di accesso utente riuscito. Quindi importa session dal pallone:

from flask import session

Abbiamo anche bisogno di impostare una chiave segreta per la sessione. Quindi in app.py , dopo che l'app è stata inizializzata, imposta la chiave segreta come mostrato:

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

Ora, all'interno di validateLogin metodo, prima di reindirizzare l'utente a /userhome dopo l'accesso, imposta la session variabile come mostrato:

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

Successivamente, all'interno di userhome metodo, controlla la variabile di sessione prima di eseguire il rendering di userhome.html . Se la variabile di sessione non viene trovata, reindirizza alla pagina di errore.

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

Salva tutte le modifiche e riavvia il server. Senza effettuare l'accesso, prova a navigare su http://localhost:5000/userhome e poiché non hai ancora effettuato l'accesso, dovresti essere reindirizzato alla pagina di errore.

Implementazione del logout

L'implementazione della funzionalità di logout è la più semplice. Tutto quello che dobbiamo fare è rendere la variabile di sessione user null e reindirizza l'utente alla pagina principale.

All'interno di app.py , crea un nuovo percorso e metodo per logout come mostrato:

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

Abbiamo già impostato l'href per il pulsante di disconnessione su /logout . Quindi salva tutte le modifiche e riavvia il server. Dalla home page, fai clic su Accedi e prova ad accedere utilizzando un indirizzo email e una password validi. Dopo aver effettuato l'accesso, fai clic su Esci pulsante nella home page dell'utente e dovresti essere disconnesso dall'applicazione.