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

Membuat Aplikasi Web dari Awal menggunakan Python Flask dan MySQL: Bagian 2

Pada bagian sebelumnya dari seri ini, kita lihat bagaimana cara memulai dengan Python Flask dan MySQL dan mengimplementasi bagian pendaftaran dari aplikasi kita. Pada tutorial ini, kita akan mengembangkannya ke tingkat berikutnya dengan membuat fitur sign-in dan logout pada aplikasi kita.
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

Indonesian (Bahasa Indonesia) translation by Aditia Dwiperdana (you can also view the original English article)

Pada bagian sebelumnya dari seri ini, kita lihat bagaimana cara memulai dengan Python Flask dan MySQL dan mengimplementasi bagian pendaftaran dari aplikasi kita. Pada tutorial ini, kita akan mengembangkannya ke tingkat berikutnya dengan membuat fitur sign-in dan logout pada aplikasi kita.

Memulai

Pertama, clone source code dari tutorial sebelumnya dari GitHub.

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

Begitu source code sudah di-clone, masuk ke direktori PythonFlaskMySQLApp---Part-1 dan jalankan server.

1
python app.py

Arahkan browser ke http://localhost:5002 dan aplikasi harusnya sudah berjalan.

Membuat Antarmuka Sign-In

Pindahlah ke PythonFlaskMySQLApp---Part-1/templates dan buat file beru bernama signin.html. Buka signin.html dan tambahkan kode HTML berikut:

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>

Buka app.py dan tambahkan sebuah rute baru untuk antarmuka sign-in.

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

Lalu, buka index.html dan signup.html, dan tambahkan tautan href untuk sign-in di kedua halaman tersebut sebagai /showSignin. Simpan semua perubahan dan restart server.

1
python app.py

Arahkan browser ke http://localhost:5002 dan klik tautan Sign In, dan kamu seharusnya melihat halaman sign-in.

Sign In pageSign In pageSign In page

Mengimplementasi Sign-In

Sekarang, kita perlu membuat fungsi untuk memvalidasi login user. Saat menekan Sign In kita akan mengirim alamat email dan password yang dimasukkan untuk memvalidasi fungsi user.

Membuat Stored Procedure

Untuk memvalidasi user, kita perlu stored procedure pada MySQL. Buatlah stored procedure MySQL seperti di bawah ini:

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 ;

Kita akan ambil detil user berdasarkan username dari databaseMySQL menggunakan sp_validateLogin. Begitu kita mendapat password yang sudah di-hash, kita akan memvalidasinya terhadap password yang dimasukkan oleh user.

Fungsi untuk Memvalidasi User

Buat sebuah fungsi untuk memvalidasi user yang akan kita panggil saat user mengirim isi 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

Seperti yang terlihat pada kode di atas, kita sudah membaca email dan password pada _username dan _password. Sekarang kita panggil sp_validateLogin dengan parameter _username. Jadi buatlah koneksi MySQL di dalam fungsi validateLogin:

1
con = mysql.connect()

Begitu koneksi terbentuk, buat sebuah cursor menggunakan koneksi con.

1
cursor = con.cursor()

Menggunakan cursor tersebut, panggil stored procedure MySQL seperti di bawah ini:

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

Ambil dokumen yang didapat dari kursor seperti berikut:

1
data = cursor.fetchall()

Jika data memiliki dokumen, kita akan mencocokkan password yang didapat dengan password yang dimasukkan oleh user.

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

Seperti yang terlihat pada kode di atas, kita menggunakan fungsi bernama check_password_hash untuk memeriksa apakah hash password yang dikembalikan sesuai dengan password yang dimasukkan oleh user. Jika semua baik-baik saja, kita akan arahkan user ke userHome.html. Dan jika ada error, kita akan tampilkan error.html bersama pesan error yang bersangkutan.

Berikut adalah kode lengkap 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()

Buat sebuah halaman bernama userHome.html di dalam folder template dan tambahkan kode HTML berikut:

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>

Buat juga sebuah halaman error bernama error.html pada folder template dan tambahkan kode HTML berikut:

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>

Di dalam error.html kita memiliki elemen seperti berikut:

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

Nilai variabel bisa dikirim dari fungsi render_template dan bisa diatur secara dinamis.

Pada sign-in yang sukses kita akan mengarahkan user ke halaman beranda user, jadi kita perlu membuat rute bernama /userHome seperti berikut:

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

Simpan semua perubahan dan restart server. Klik tautan Sign In di halaman beranda dan coba untuk sign in menggunakan alamat email dan password yang valid. Pada validasi user yang berhasil, kamu akan melihat halaman seperti berikut:

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

Pada validasi user yang gagal user akan diarahkan ke halaman error seperti berikut:

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

Di sini kita menggunakan halaman error yang berbeda untuk menampilkan error. Tidak masalah jika kamu ingin menggunakan halaman yang sama untuk menampilkan pesan error.

Mencegah Akses ke Beranda User yang tidak Sah

Pada validasi user yang sukses user diairahkan ke halaman beranda user. Tapi sekarang bahkan user tidak sah bisa melihat halaman beranda dengan mengetik URL http://localhost:5002/userHome.

Untuk mencegah akses user tidak sah, kita akan periksa variabel session yang akan kita atur saat user login yang berhasil. Jadi impor session dari flask:

1
from flask import session

Kita juga perlu mengatur kunci rahasia untuk session. Jadi pada app.py, setelah aplikasi diinisialisasi, atur kunci rahasia sebagai berikut:

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

Sekarang, di dalam fungsi validateLogin, sebelum mengarahkan user ke /userHome pada sign-in yang sukses, atur variabel session seperti ini:

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

Berikutnya, dalam fungsi userHome, periksa variabel session sebelum menampilkan userHome.html. Jika variabel session tidak ditemukan, arahkan ke halaman error.

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

Simpan semua perubahan dan restart server. Tanpa sign-in, cobalah membuka http://localhost:5002/userHome dan karena kamu tidak log in, kamu harusnya diarahkan ke halaman error.

Unauthorized access errorUnauthorized access errorUnauthorized access error

Mengimplementasi Logout

Implementasi fitur logout adalah yang paling mudah. Yang perlu kita lakukan kadalah membuat variabel session user menjadi null dan mengarahkan user kembali ke halaman utama.

Di dalam app.py, buat rute baru dan fungsi untuk logout seperti berikut:

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

Kita sudah mengatur href untuk tombol logout ke /logout. Simpan semua perubahan dan restart server. Dari halaman utama, klik Sign In dan cobalah login menggunakan email dan password yang valid. Begitu berhasil sign in, klik tombol Logout di beranda user dan kamu harusnya bisa log out dari aplikasi.

Kesimpulan

Pada tutorial bagian ini, kita lihat bagaimana cara mengimplementasi fitur user login dan logout. Kita juga lihat bagaimana mencegah akses tidak sah terhadap halaman aplikasi. Pada tutorial bagian berikutnya, kita akan mengimplementasi fitur untuk user yang sudah login dan untuk menambahkan dan mengedit blog post dalam aplikasi.

Source code untuk tutorial ini tersedia di GitHub.

Beri tahu kami pendapat kamu di komentar di bawah!