Advertisement
  1. Code
  2. Coding Fundamentals
  3. Databases & SQL

Creazione di una Web App da zero utilizzando Python Flask e MySQL : Parte 2

Nell'articolo precedente di questa serie, abbiamo visto come iniziare  con Python Flask e MySQL , e realizzato il modulo di registrazione della nostra applicazione. In questo tutorial, porteremo l'argomento al  livello successivo implementando le funzionalità di accesso e di uscita della nostra applicazione.
Scroll to top
This post is part of a series called Creating a Web App From Scratch Using Python Flask and MySQL.
Creating a Web App From Scratch Using Python Flask and MySQL
Creating a Web App From Scratch Using Python Flask and MySQL: Part 3

Italian (Italiano) translation by Piergiorgio Sansone (you can also view the original English article)

Nell'articolo precedente di questa serie, abbiamo visto come iniziare  con Python Flask e MySQL , e realizzato il modulo di registrazione della nostra applicazione. In questo tutorial, porteremo l'argomento al  livello successivo implementando le funzionalità di accesso e di uscita della nostra applicazione.

Iniziamo 

Innanzitutto copiate il codice sorgente del tutorial precedente da GitHub.

1
git clone https://github.com/jay3dec/PythonFlaskMySQLApp---Part-1.git

Una volta copiato il codice, navigate la directory PythonFlaskMySQLApp---Parte-1 e riavviate il server 

1
python app.py

Puntate il browser su http://localhost:5002 e dovreste vedere l'applicazione girare.

Creazione dell'interfaccia di Sign-In

Navigate la directory PythonFlaskMySQLApp---Part-1/templates e create un nuovo file chiamato signin.html. Aprite il file signin.html ed aggiungete il codice HTML seguente:

1
<!DOCTYPE html>
2
<html lang="en">
3
  <head>
4
    <title>Python Flask Bucket List App</title>
5
6
   
7
    <link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
8
9
    <link href="http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
10
    <link href="../static/css/signup.css" rel="stylesheet">
11
    <script src="../static/js/jquery-1.11.2.js"></script>
12
   
13
  </head>
14
15
  <body>
16
17
    <div class="container">
18
      <div class="header">
19
        <nav>
20
          <ul class="nav nav-pills pull-right">
21
            <li role="presentation" ><a href="/">Home</a></li>
22
            <li role="presentation" class="active"><a href="#">Sign In</a></li>
23
            <li role="presentation" ><a href="/showSignUp">Sign Up</a></li>
24
          </ul>
25
        </nav>
26
        <h3 class="text-muted">Python Flask App</h3>
27
      </div>
28
29
      <div class="jumbotron">
30
        <h1>Bucket List App</h1>
31
        <form class="form-signin" action="/validateLogin" method="post">
32
        <label for="inputEmail" class="sr-only">Email address</label>
33
        <input type="email" name="inputEmail" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
34
        <label for="inputPassword" class="sr-only">Password</label>
35
        <input type="password" name="inputPassword" id="inputPassword" class="form-control" placeholder="Password" required>
36
        
37
        <button id="btnSignIn" class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
38
      </form>
39
      </div>
40
41
      
42
43
      <footer class="footer">
44
        <p>&copy; Company 2015</p>
45
      </footer>
46
47
    </div>
48
  </body>
49
</html>

Aprite il file app.py ed aggiungete il nuovo percorso all'interfaccia sign-in. 

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

Poi aprite index.html e signup.html, aggiungete il codice href del link a sign-in in entrambe le pagine come /showSingin. Salvare tutte le modifiche e riavviare il server.

1
python app.py

Puntate il browser su http://localhost:5002 e cliccate sul link Sign In , e dovreste essere in grado di vedere la pagina di registrazione.

Sign In pageSign In pageSign In page

Implementazione di Sign-In

Adesso, dobbiamo creare la funzione per la validazione dell'accesso utente. Cliccando Sing In inviamo l'indirizzo email e la password inseriti alla funzione di valutazione utente.

Creazione di una Stored Procedure

Per convalidare un utente, abbiamo bisogno di una procedura di MySQL memorizzati. Quindi create una stored procedure MySQL come mostrato:

1
DELIMITER $$
2
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_validateLogin`(
3
IN p_username VARCHAR(20)
4
)
5
BEGIN
6
    select * from tbl_user where user_username = p_username;
7
END$$
8
DELIMITER ;

Otterremo i dettagli dell'utente,  in base allo username,  dal database MySQL utilizzando sp_validateLogin. Una volta ottenuta la password nascosta la confronteremo con la password inserita dall'utente.

Convalidare il metodo utente

Create un metodo per convalidare l'utente che chiameremo quando l'utente invia il form:

1
@app.route('/validateLogin',methods=['POST'])
2
def validateLogin():
3
    try:
4
        _username = request.form['inputEmail']
5
        _password = request.form['inputPassword']
6
7
    except Exception as e:
8
        return render_template('error.html',error = str(e))
9

Come si vede nel codice precedente, abbiamo letto l'indirizzo email registrato e la password in _username e _password. Ora chiameremo la procedura di sp_validateLogin con il parametro _username. Quindi create una connessione MySQL all'interno del metodo validateLogin:

1
con = mysql.connect()

Una volta che la connessione è stata creata, creare un cursore utilizzando la connessione con.

1
cursor = con.cursor()

Utilizzando il cursore, chiamate la stored procedure di MySQL come mostrato:

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

Ottenete i record recuperati dalla posizione del cursore come indicato:

1
data = cursor.fetchall()

Se il dato è presente, verificheremo la password recuperata con la password immessa dall'utente.

1
if len(data) > 0:
2
    if check_password_hash(str(data[0][3]),_password):
3
        return redirect('/userHome')
4
    else:
5
        return render_template('error.html',error = 'Wrong Email address or Password.')
6
else:
7
    return render_template('error.html',error = 'Wrong Email address or Password.')

Come si vede nel codice precedente, abbiamo utilizzato un metodo chiamato check_password_hash per controllare se la password nascosta restituito corrisponde alla password immessa dall'utente. Se tutto è a posto quindi reindirizzeremo l'utente a userHome.html. E se ci fosse un errore , visualizzeremo la pagina error.html con il messaggio di errore.

Ecco il codice completo validateLogin:

1
@app.route('/validateLogin',methods=['POST'])
2
def validateLogin():
3
    try:
4
        _username = request.form['inputEmail']
5
        _password = request.form['inputPassword']
6
7
8
9
        # connect to mysql

10
11
        con = mysql.connect()
12
        cursor = con.cursor()
13
        cursor.callproc('sp_validateLogin',(_username,))
14
        data = cursor.fetchall()
15
16
17
18
19
        if len(data) > 0:
20
            if check_password_hash(str(data[0][3]),_password):
21
                session['user'] = data[0][0]
22
                return redirect('/userHome')
23
            else:
24
                return render_template('error.html',error = 'Wrong Email address or Password.')
25
        else:
26
            return render_template('error.html',error = 'Wrong Email address or Password.')
27
28
29
    except Exception as e:
30
        return render_template('error.html',error = str(e))
31
    finally:
32
        cursor.close()
33
        con.close()

Create una pagina denominata userHome.html all'interno della cartella modelli e aggiungere il seguente codice HTML:

1
<!DOCTYPE html>
2
<html lang="en">
3
4
<head>
5
    <title>Python Flask Bucket List App</title>
6
7
8
    <link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
9
10
    <link href="http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
11
    <link href="../static/css/signup.css" rel="stylesheet">
12
13
14
</head>
15
16
<body>
17
18
    <div class="container">
19
        <div class="header">
20
            <nav>
21
                <ul class="nav nav-pills pull-right">
22
                    <li role="presentation" class="active"><a href="/logout">Logout</a>
23
                    </li>
24
                </ul>
25
            </nav>
26
            <h3 class="text-muted">Python Flask App</h3>
27
        </div>
28
29
        <div class="jumbotron">
30
            <h1>Welcome Home !!</h1>
31
32
        </div>
33
34
35
        <footer class="footer">
36
            <p>&copy; Company 2015</p>
37
        </footer>
38
39
    </div>
40
</body>
41
42
</html>

Create anche una pagina di errore chiamata error.html nella cartella templates e aggiungere il seguente codice HTML:

1
<!DOCTYPE html>
2
<html lang="en">
3
4
<head>
5
    <title>Unauthorized Access:: Python Flask Bucket List App</title>
6
7
8
    <link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet">
9
10
    <link href="http://getbootstrap.com/examples/jumbotron-narrow/jumbotron-narrow.css" rel="stylesheet">
11
12
13
</head>
14
15
<body>
16
17
    <div class="container">
18
        <div class="header">
19
            <nav>
20
                <ul class="nav nav-pills pull-right">
21
                    <li role="presentation" class="active"><a href="#">Home</a>
22
                    </li>
23
                    <li role="presentation"><a href="/showSignin">Sign In</a>
24
                    </li>
25
                    <li role="presentation"><a href="/showSignUp">Sign Up</a>
26
                    </li>
27
                </ul>
28
            </nav>
29
            <h3 class="text-muted">Python Flask App</h3>
30
        </div>
31
32
        <div class="jumbotron">
33
            <h1>{{error}}</h1>
34
        </div>
35
36
37
38
        <footer class="footer">
39
            <p>&copy; Company 2015</p>
40
        </footer>
41
42
    </div>
43
</body>
44
45
</html>

All'interno di error.html abbiamo un elemento come mostrato:

1
<h1>{{error}}</h1>

Il valore per la variabile può essere passato dalla funzione render_template e può essere impostato in modo dinamico.

Con un accesso corretto reindirizziamo l'utente alla sua home page  quindi dobbiamo creare un percorso chiamato /userHome come illustrato:

1
@app.route('/userHome')
2
def userHome():
3
    return render_template('userHome.html')
4
    

Salvare tutte le modifiche e riavviare il server. Cliccate il link Sign in nella home page e tentate di accedere utilizzando un indirizzo email valido e una password. Con la convalida dell'utente con successo, dovreste avere una pagina come mostrato sotto:

User home on successful user sign inUser home on successful user sign inUser home on successful user sign in

Con una validazione dell'utente non corretta, verrebbe reindirizzato verso una pagine di errore come mostrato sotto: 

Error message on unsuccessful user sign inError message on unsuccessful user sign inError message on unsuccessful user sign in

Qui abbiamo usato una pagina di errore separata per visualizzare l'errore. Va anche bene se si desidera utilizzare la stessa pagina per visualizzare il messaggio di errore.

Limitare l'accesso non autorizzato alla utente Home Page

L'utente correttamente validato viene reindirizzato verso la sua home page. Ma adesso anche un utente non autorizzato può visualizzare la home page selezionando semplicemente la URL http://localhost:5002/userHome.

Per limitare l'accesso di utenti non autorizzati, controlleremo con una variabile di sessione che viene configurata quando l'utente accede con successo. Quindi importate session  da Flask:

1
from flask import session

Abbiamo anche bisogno di impostare una chiave segreta per la sessione. Così nel app.py, dopo l'applicazione come stato inizializzato, impostate la chiave segreta come indicato:

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

Ora, all'interno del metodo di validateLogin, prima di reindirizzare l'utente a /userHome dopo l'accesso corretto, impostate la variabile di sessione come illustrato:

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

Quindi all'interno del metodo userHome, controllate la variabile di sessione prima della visualizzazione della pagina userHome.html. Se la variabile di sessione non viene trovata, reindirizzate alla pagina di errore.

1
@app.route('/userHome')
2
def userHome():
3
    if session.get('user'):
4
        return render_template('userHome.html')
5
    else:
6
        return render_template('error.html',error = 'Unauthorized Access')

Salvare tutte le modifiche e riavviare il server. Senza effettuare l'accesso, provare a navigare a http://localhost:5002/userHome e dal momento che non ti sei loggato ancora, dovreste essere reindirizzati alla pagina di errore.

Unauthorized access errorUnauthorized access errorUnauthorized access error

Implementazione del Logout

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

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

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

Abbiamo già impostato l' href per il pulsante di disconnessione a /logout. Quindi salvare tutte le modifiche e riavviare il server. Dalla home page, fare clic su Sign In e tentate di accedere utilizzando un indirizzo email valido e una password. Una volta effettuato l'accesso, fare clic sul pulsante di Logout nella home dell'utente ed è necessario essere connessi con successo dall'applicazione.

Conclusione

In questa parte del tutorial, abbiamo visto come implementare la funzionalità di login e logout utente. Abbiamo anche visto come limitare l'accesso non autorizzato alle pagine dell'applicazione. Nella prossima parte di questo tutorial, implementeremo la funzionalità per l'utente loggato di aggiungere e modificare un post del blog nell'applicazione.

Il codice sorgente da questo tutorial è disponibile su GitHub.

Fateci sapere i vostri pensieri nei commenti qui sotto!

Advertisement
Advertisement