Mengizinkan pengguna untuk log masuk ke aplikasi Anda adalah salah satu fitur paling umum yang akan ditambahkan ke aplikasi web Anda. Artikel ini akan membahas cara menambah autentikasi ke aplikasi Flask Anda dengan paket Flask-Login.
Kita akan membangun beberapa laman pendaftaran dan log masuk yang memungkinkan pengguna untuk log masuk dan mengakses laman-laman yang terlindungi, sedangkan pengguna yang tidak log masuk tidak dapat melihatnya. Kita akan mengambil informasi dari model pengguna dan menampilkannya di laman terlindungi kita ketika pengguna log masuk untuk menyimulasikan tampilan profil.
Kita akan membahas yang berikut dalam artikel ini:
Kode sumber untuk proyek ini tersedia di GitHub.
Untuk mengikuti tutorial ini, Anda membutuhkan hal berikut ini:
Aplikasi kita akan menggunakan setelan pabrik aplikasi Flask dengan cetak biru. Kita akan memiliki satu cetak biru yang menangani segala sesuatu yang terkait dengan auth, dan kita akan memiliki cetak biru lainnya untuk rute reguler kita, yang termasuk indeks dan laman profil terlindungi. Dalam aplikasi sungguhan, Anda dapat mengurai fungsionalitas dengan cara apa pun yang Anda suka, tetapi solusi yang dibahas di sini akan bekerja dengan baik untuk tutorial ini.
Berikut adalah diagram untuk memberikan gambaran tentang struktur berkas proyek Anda akan terlihat seperti apa setelah Anda menyelesaikan tutorial:
.
└── flask_auth_app
└── project
├── __init__.py # setup our app
├── auth.py # the auth routes for our app
├── db.sqlite # our database
├── main.py # the non-auth routes for our app
├── models.py # our user model
└── templates
├── base.html # contains common layout and links
├── index.html # show the home page
├── login.html # show the login form
├── profile.html # show the profile page
└── signup.html # show the signup form
Seiring kita menjalani tutorial ini, kita akan menciptakan direktori dan berkas ini.
Ada tiga paket utama yang diperlukan untuk proyek kita:
Kita akan menggunakan SQLite untuk menghindari keharusan menginstal dependensi tambahan bagi basis data.
Pertama-tama, kita akan mulai dengan menciptakan direktori proyek:
- mkdir flask_auth_app
Selanjutnya, kita perlu bernavigasi ke direktori proyek:
- cd flask_auth_app
Anda akan ingin menciptakan lingkungan Python jika Anda tidak memilikinya. Tergantung bagaimana Python terinstal pada mesin Anda, perintah Anda akan terlihat mirip seperti ini:
- python3 -m venv auth
- source auth/bin/activate
Catatan: Anda dapat melihat tutorial yang relevan dengan lingkungan lokal untuk menyiapkan venv
.
Jalankan perintah berikut dari lingkungan virtual Anda untuk menginstal paket yang diperlukan:
- pip install flask flask-sqlalchemy flask-login
Karena kini Anda telah menginstal paket, Anda siap untuk menciptakan berkas aplikasi utama.
Mari kita mulai dengan menciptakan direktori project
:
- mkdir project
Berkas pertama yang akan kita kerjakan adalah berkas __init__.py
untuk proyek kita:
- nano project/__init__.py
Berkas ini akan memiliki fungsi untuk menciptakan aplikasi kita, yang akan menginisialisasi basis data dan mendaftarkan cetak biru kita. Saat ini, berkas ini tidak terlalu berguna, tetapi akan diperlukan selanjutnya untuk aplikasi kita. Kita perlu menginisialisasi SQLAlchemy, menetapkan beberapa nilai konfigurasi, dan mendaftarkan cetak biru kita di sini.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# init SQLAlchemy so we can use it later in our models
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret-key-goes-here'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
db.init_app(app)
# blueprint for auth routes in our app
from .auth import auth as auth_blueprint
app.register_blueprint(auth_blueprint)
# blueprint for non-auth parts of app
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
return app
Setelah memiliki berkas aplikasi utama, kita dapat mulai menambahkan ke dalam rute kita.
Untuk rute, kita akan menggunakan dua cetak biru. Untuk cetak biru utama, kita akan memiliki laman beranda (/
) dan laman profil (/profile
) untuk setelah kita log masuk. Jika pengguna mencoba mengakses laman profil tanpa log masuk, mereka akan dikirim ke rute log masuk.
Untuk cetak biru auth, kita akan memiliki rute untuk mengambil baik laman log masuk (/login
) dan laman pendaftaran (/sign-up
). Kita juga akan memiliki rute untuk menangani permintaan POST dari kedua rute itu. Terakhir, kita akan memiliki rute log keluar (/logout
) untuk mengeluarkan pengguna aktif.
Untuk sementara ini, kita akan mendefinisikan login
, signup
, dan logout
dengan respons sederhana. Kita akan meninjaunya kembali pada langkah selanjutnya dan memperbaruinya dengan fungsionalitas yang diinginkan.
Pertama-tama, ciptakan main.py
untuk main_blueprint
:
- nano project/main.py
from flask import Blueprint
from . import db
main = Blueprint('main', __name__)
@main.route('/')
def index():
return 'Index'
@main.route('/profile')
def profile():
return 'Profile'
Selanjutnya, ciptakan auth.py
untuk auth_blueprint
:
- nano project/auth.py
from flask import Blueprint
from . import db
auth = Blueprint('auth', __name__)
@auth.route('/login')
def login():
return 'Login'
@auth.route('/signup')
def signup():
return 'Signup'
@auth.route('/logout')
def logout():
return 'Logout'
Di dalam terminal, Anda dapat menetapkan nilai FLASK_APP
dan FLASK_DEBUG
:
- export FLASK_APP=project
- export FLASK_DEBUG=1
Variabel lingkungan FLASK_APP
memberi instruksi pada Flask terkait cara memuat aplikasi. Ini harus mengarah ke tempat create_app
berada. Untuk keperluan kita, kita akan mengarahkan ke direktori project
.
Variabel lingkungan FLASK_DEBUG
diaktifkan dengan menetapkan nilainya menjadi 1
. Ini akan mengaktifkan pengawakutu yang akan menampilkan kesalahan aplikasi di peramban.
Pastikan Anda berada di direktori flask_auth_app
, lalu jalankan proyeknya:
- flask run
Sekarang, dalam peramban web, Anda seharusnya dapat bernavigasi ke lima URL yang memungkinkan dan melihat teks yang dihasilkan yang didefinisikan dalam auth.py
dan main.py
.
Misalnya, mengunjungi localhost:5000/profile
akan menampilkan: Profile
:
Kini setelah kita memverifikasi bahwa rute berperilaku seperti yang diharapkan, kita dapat melanjutkan ke penciptaan templat.
Mari kita lanjutkan dan menciptakan templat yang digunakan dalam aplikasi. Ini adalah langkah pertama sebelum kita dapat menerapkan fungsionalitas log masuk yang sebenarnya. Aplikasi kita akan menggunakan empat templat:
Kita juga akan memiliki templat dasar yang akan memiliki kode umum untuk setiap lamannya. Dalam hal ini, templat dasar akan memiliki tautan navigasi dan tata letak umum dari laman. Mari kita ciptakan sekarang.
Pertama-tama, ciptakan direktori template
di bawah direktori project
:
- mkdir -p project/templates
Kemudian, ciptakan base.html
:
- nano project/templates/base.html
Selanjutnya, tambahkan kode berikut ke berkas base.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Flask Auth Example</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css" />
</head>
<body>
<section class="hero is-primary is-fullheight">
<div class="hero-head">
<nav class="navbar">
<div class="container">
<div id="navbarMenuHeroA" class="navbar-menu">
<div class="navbar-end">
<a href="{{ url_for('main.index') }}" class="navbar-item">
Home
</a>
<a href="{{ url_for('main.profile') }}" class="navbar-item">
Profile
</a>
<a href="{{ url_for('auth.login') }}" class="navbar-item">
Login
</a>
<a href="{{ url_for('auth.signup') }}" class="navbar-item">
Sign Up
</a>
<a href="{{ url_for('auth.logout') }}" class="navbar-item">
Logout
</a>
</div>
</div>
</div>
</nav>
</div>
<div class="hero-body">
<div class="container has-text-centered">
{% block content %}
{% endblock %}
</div>
</div>
</section>
</body>
</html>
Kode ini akan menciptakan serangkaian menu yang terhubung ke setiap laman dari aplikasi dan daerah tempat konten akan muncul.
Catatan: Di balik layar, kita menggunakan Bulma untuk menangani pengaturan gaya dan tata letak. Untuk pengetahuan yang lebih dalam tentang Bulma, pertimbangkan untuk membaca dokumentasi Bulma resmi.
Selanjutnya, ciptakan templates/index.html
:
- nano project/templates/index.html
Tambahkan kode berikut ke berkas yang baru saja diciptakan untuk menambahkan konten ke laman:
{% extends "base.html" %}
{% block content %}
<h1 class="title">
Flask Login Example
</h1>
<h2 class="subtitle">
Easy authentication and authorization in Flask.
</h2>
{% endblock %}
Kode ini akan menciptakan laman indeks dasar dengan judul dan subjudul.
Selanjutnya, ciptakan templates/login.html
:
- nano project/templates/login.html
Kode ini menghasilkan laman log masuk dengan bidang untuk Surel dan Kata Sandi. Ada juga kotak centang untuk “mengingat” suatu sesi log masuk.
{% extends "base.html" %}
{% block content %}
<div class="column is-4 is-offset-4">
<h3 class="title">Login</h3>
<div class="box">
<form method="POST" action="/login">
<div class="field">
<div class="control">
<input class="input is-large" type="email" name="email" placeholder="Your Email" autofocus="">
</div>
</div>
<div class="field">
<div class="control">
<input class="input is-large" type="password" name="password" placeholder="Your Password">
</div>
</div>
<div class="field">
<label class="checkbox">
<input type="checkbox">
Remember me
</label>
</div>
<button class="button is-block is-info is-large is-fullwidth">Login</button>
</form>
</div>
</div>
{% endblock %}
Selanjutnya, ciptakan templates/signup.html
:
- nano project/templates/signup.html
Tambahkan kode berikut untuk menciptakan laman pendaftaran dengan bidang untuk surel, nama, dan kata sandi:
{% extends "base.html" %}
{% block content %}
<div class="column is-4 is-offset-4">
<h3 class="title">Sign Up</h3>
<div class="box">
<form method="POST" action="/signup">
<div class="field">
<div class="control">
<input class="input is-large" type="email" name="email" placeholder="Email" autofocus="">
</div>
</div>
<div class="field">
<div class="control">
<input class="input is-large" type="text" name="name" placeholder="Name" autofocus="">
</div>
</div>
<div class="field">
<div class="control">
<input class="input is-large" type="password" name="password" placeholder="Password">
</div>
</div>
<button class="button is-block is-info is-large is-fullwidth">Sign Up</button>
</form>
</div>
</div>
{% endblock %}
Selanjutnya, ciptakan templates/profile.html
:
- nano project/templates/profile.html
Tambahkan kode ini untuk menciptakan laman sederhana dengan judul yang dikodekan secara permanen untuk menyambut Anthony:
{% extends "base.html" %}
{% block content %}
<h1 class="title">
Welcome, Anthony!
</h1>
{% endblock %}
Nanti, kita akan menambahkan kode untuk menyapa pengguna siapa pun secara dinamis.
Setelah Anda menambah templat, kita dapat memperbarui pernyataan respons di setiap rute ketika kita harus memberikan templat alih-alih teks.
Selanjutnya, perbarui main.py
dengan memodifikasi baris impor dan rute untuk index
dan profile
:
from flask import Blueprint, render_template
...
@main.route('/')
def index():
return render_template('index.html')
@main.route('/profile')
def profile():
return render_template('profile.html')
Sekarang Anda akan memperbarui auth.py
dengan memodifikasi baris impor dan rute untuk login
dan signup
:
from flask import Blueprint, render_template
...
@auth.route('/login')
def login():
return render_template('login.html')
@auth.route('/signup')
def signup():
return render_template('signup.html')
Setelah Anda membuat perubahan ini, laman pendaftaran akan terlihat seperti ini jika Anda bernavigasi ke /sign-up
:
Anda seharusnya dapat melihat laman untuk /
, /login
, dan /profile
juga.
Kita akan membiarkan /logout
untuk saat ini karena /logout tidak akan menampilkan templat saat selesai.
Model pengguna kita mewakili seberapa berartinya memiliki pengguna bagi aplikasi kita. Kita akan memiliki bidang untuk alamat surel, kata sandi, dan nama. Di aplikasi, Anda mungkin memutuskan bahwa Anda menginginkan lebih banyak informasi untuk disimpan per pengguna. Anda dapat menambah hal-hal seperti ulang tahun, foto profil, lokasi, atau preferensi pengguna apa pun.
Model yang diciptakan dalam Flask-SQLAlchemy diwakili oleh kelas-kelas yang kemudian diterjemahkan ke tabel-tabel di dalam basis data. Atribut dari kelas-kelas itu lalu berubah menjadi kolom-kolom untuk tabel tersebut.
Mari kita lanjutkan dan ciptakan model pengguna itu:
- nano project/models.py
Kode ini menciptakan model pengguna dengan kolom untuk id
, email
, password
, dan name
:
from . import db
class User(db.Model):
id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy
email = db.Column(db.String(100), unique=True)
password = db.Column(db.String(100))
name = db.Column(db.String(1000))
Karena kini Anda telah menciptakan model pengguna, Anda dapat melanjutkan ke mengonfigurasi basis data.
Seperti yang tercantum di dalam Prasyarat, kita akan menggunakan basis data SQLite. Kita dapat menciptakan basis data SQLite sendiri, tetapi mari kita biarkan Flask-SQLAlchemy yang melakukannya untuk kita. Kita telah memiliki jalur basis data yang ditentukan dalam berkas __init__.py
, sehingga kita hanya perlu memberi tahu Flask-SQLAlchemy untuk menciptakan basis data di Python REPL.
Jika Anda menghentikan aplikasi dan membuka Python REPL, kita dapat menciptakan basis data menggunakan metode create_all
pada objek db
. Pastikan Anda masih berada di lingkungan virtual dan di dalam direktori >flask_auth_app
.
- from project import db, create_app, models
- db.create_all(app=create_app()) # pass the create_app result so Flask-SQLAlchemy gets the configuration.
Catatan: Jika menggunakan penafsir Python merupakan hal baru bagi Anda, Anda dapat melihat dokumentasi resmi.
Sekarang Anda akan melihat berkas db.sqlite
di dalam direktori proyek. Basis data ini akan memiliki tabel pengguna kita di dalamnya.
Untuk fungsi pendaftaran, kita akan mengambil data yang diketik pengguna ke dalam formulir dan menambahkannya ke dalam basis data kita. Sebelum menambahkannya, kita perlu memastikan bahwa pengguna tidak ada di basis data. Jika pengguna tidak ada, kita perlu memastikan kita melakukan hash kata sandi sebelum menempatkannya ke dalam basis data karena kita tidak mau kata sandi kita disimpan dalam teks polos.
Mari kita mulai dengan menambahkan fungsi kedua untuk menangani data formulir POST. Dalam fungsi ini, kita akan mengumpulkan data yang diwariskan dari pengguna terlebih dahulu.
Ciptakan fungsi dan tambahkan pengalihan di bagian bawah. Perintah ini akan memberikan pengalaman pengguna dari pendaftaran yang berhasil dan diarahkan ke Laman Log Masuk.
Perbarui auth.py
dengan memodifikasi baris impor dan menerapkan signup_post
:
from flask import Blueprint, render_template, redirect, url_for
...
@auth.route('/signup', methods=['POST'])
def signup_post():
# code to validate and add user to database goes here
return redirect(url_for('auth.login'))
Sekarang, mari kita tambahkan sisa kode yang diperlukan untuk mendaftarkan pengguna.
Untuk memulai, kita harus menggunakan objek yang diminta untuk mendapatkan data formulir.
Lanjutkan untuk memperbarui auth.py
dengan menambahkan impor dan menerapkan signup_post
:
from flask import Blueprint, render_template, redirect, url_for, request
from werkzeug.security import generate_password_hash, check_password_hash
from .models import User
from . import db
...
@auth.route('/signup', methods=['POST'])
def signup_post():
email = request.form.get('email')
name = request.form.get('name')
password = request.form.get('password')
user = User.query.filter_by(email=email).first() # if this returns a user, then the email already exists in database
if user: # if a user is found, we want to redirect back to signup page so user can try again
return redirect(url_for('auth.signup'))
# create a new user with the form data. Hash the password so the plaintext version isn't saved.
new_user = User(email=email, name=name, password=generate_password_hash(password, method='sha256'))
# add the new user to the database
db.session.add(new_user)
db.session.commit()
return redirect(url_for('auth.login'))
Catatan: Menyimpan kata sandi dalam teks polos adalah praktik keamanan yang buruk. Anda umumnya akan ingin memanfaatkan algoritma hash yang kompleks dan suatu garam kata sandi agar kata sandi tetap aman.
Karena kini kita telah menyelesaikan metode pendaftaran, kita seharusnya dapat menciptakan pengguna baru. Gunakan formulir untuk menciptakan pengguna.
Ada dua cara untuk memverifikasi jika pendaftaran berhasil: Anda dapat menggunakan penampil basis data untuk melihat baris yang ditambahkan ke tabel, atau Anda dapat mencoba mendaftar dengan alamat surel yang sama lagi, dan jika Anda mendapat pesan kesalahan, Anda tahu bahwa surel pertama telah disimpan dengan benar. Mari kita coba pendekatan itu.
Kita dapat menambahkan kode untuk menginformasikan pengguna bahwa surel sudah ada dan memberi tahu mereka untuk pergi ke laman log masuk. Dengan memanggil fungsi flash
, kita akan mengirim pesan ke permintaan selanjutnya, yang dalam hal ini adalah pengalihan. Laman yang kita kunjungi akan memiliki akses ke pesan itu di dalam templat.
Pertama-tama, kita tambahkan flash
sebelum kita mengalihkan kembali ke laman pendaftaran.
from flask import Blueprint, render_template, redirect, url_for, request, flash
...
@auth.route('/signup', methods=['POST'])
def signup_post():
...
if user: # if a user is found, we want to redirect back to signup page so user can try again
flash('Email address already exists')
return redirect(url_for('auth.signup'))
Untuk mendapatkan pesan flash di dalam templat, kita dapat menambahkan kode ini di atas formulir. Ini akan menampilkan pesan secara langsung di atas formulir.
...
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="notification is-danger">
{{ messages[0] }}. Go to <a href="{{ url_for('auth.login') }}">login page</a>.
</div>
{% endif %}
{% endwith %}
<form method="POST" action="/signup">
Metode log masuk mirip dengan fungsi pendaftaran dalam hal kita akan mengambil informasi pengguna dan melakukan sesuatu dengannya. Dalam kasus ini, kita akan membandingkan alamat surel yang dimasukkan untuk melihat apakah alamat itu ada di dalam basis data. Jika demikian, kita akan menguji kata sandi yang disediakan pengguna dengan melakukan hash kata sandi yang diberikan pengguna dan membandingkannya dengan kata sandi yang telah melalui proses hash yang ada di dalam basis data. Kita tahu pengguna telah memasukkan kata sandi yang benar saat kedua kata sandi yang telah melalui proses hash sesuai.
Setelah pengguna melewati pemeriksaan kata sandi, kita tahu bahwa pengguna itu memiliki kredensial yang benar dan kita dapat membuat mereka log masuk menggunakan Flask-Login. Dengan memanggil login_user
, Flask-Login akan menciptakan sesi untuk pengguna tersebut yang akan tetap aktif selama pengguna tetap log masuk, yang akan memungkinkan pengguna untuk melihat laman terlindungi.
Kita dapat memulai dengan rute baru untuk menangani data POSTed. Kita akan mengalihkan ke laman profil saat pengguna berhasil log masuk:
...
@auth.route('/login', methods=['POST'])
def login_post():
# login code goes here
return redirect(url_for('main.profile'))
Sekarang, kita perlu memverifikasi apakah pengguna memiliki kredensial yang benar:
...
@auth.route('/login', methods=['POST'])
def login_post():
email = request.form.get('email')
password = request.form.get('password')
remember = True if request.form.get('remember') else False
user = User.query.filter_by(email=email).first()
# check if the user actually exists
# take the user-supplied password, hash it, and compare it to the hashed password in the database
if not user or not check_password_hash(user.password, password):
flash('Please check your login details and try again.')
return redirect(url_for('auth.login')) # if the user doesn't exist or password is wrong, reload the page
# if the above check passes, then we know the user has the right credentials
return redirect(url_for('main.profile'))
Mari kita tambahkan blok ke dalam templat sehingga pengguna dapat melihat pesan flash. Seperti formulir pendaftaran, mari kita tambahkan pesan kesalahan potensial secara langsung di atas formulir:
...
{% with messages = get_flashed_messages() %}
{% if messages %}
<div class="notification is-danger">
{{ messages[0] }}
</div>
{% endif %}
{% endwith %}
<form method="POST" action="/login">
Kini kita telah memiliki kemampuan untuk mengatakan pengguna telah berhasil log masuk, tetapi pengguna tidak masuk ke mana pun. Ini adalah saat kita menggunakan Flask-Login untuk mengelola sesi pengguna.
Sebelum kita memulai, kita memerlukan beberapa hal agar Flask-Login bekerja. Mulai dengan menambahkan UserMixin
ke model Pengguna Anda. UserMixin
akan menambahkan atribut Flask-Login ke model sehingga Flask-Login akan dapat bekerja dengannya.
from flask_login import UserMixin
from . import db
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy
email = db.Column(db.String(100), unique=True)
password = db.Column(db.String(100))
name = db.Column(db.String(1000))
Kemudian, kita perlu menentukan pemuat pengguna kita. Pemuat pengguna memberi tahu Flask-Login cara menemukan pengguna tertentu dari ID yang disimpan di dalam kuki sesi mereka. Kita dapat menambahkan ini ke dalam fungsi create_app
bersama dengan kode init
untuk Flask-Login:
...
from flask_login import LoginManager
...
def create_app():
...
db.init_app(app)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
from .models import User
@login_manager.user_loader
def load_user(user_id):
# since the user_id is just the primary key of our user table, use it in the query for the user
return User.query.get(int(user_id))
Terakhir, kita dapat menambahkan fungsi login_user
sebelum kita mengalihkan ke laman profil untuk menciptakan sesi:
from flask_login import login_user
from .models import User
...
@auth.route('/login', methods=['POST'])
def login_post():
...
# if the above check passes, then we know the user has the right credentials
login_user(user, remember=remember)
return redirect(url_for('main.profile'))
Dengan penyiapan Flask-Login, kita dapat menggunakan rute /login
. Ketika semuanya disiapkan dengan benar, Anda akan melihat laman profil.
Jika nama Anda bukan Anthony, Anda akan melihat bahwa nama Anda salah. Kita ingin profil menampilkan nama yang ada di dalam basis data. Pertama-tama, kita perlu melindungi laman itu, kemudian mengakses data pengguna untuk mendapatkan namanya.
Untuk melindungi laman saat menggunakan Flask-Login, kita menambahkan dekorator @login_required
antara rute dan fungsi. Ini akan mencegah pengguna yang tidak log masuk untuk melihat rute. Jika pengguna tidak log masuk, pengguna akan dialihkan ke laman log masuk, sesuai konfigurasi Flask-Login.
Dengan rute yang dilengkapi oleh dekorator @login_required
, kita akan memiliki kemampuan untuk menggunakan objek current_user
di dalam fungsi. current_user
ini mewakili pengguna dari basis data, dan kita dapat mengakses semua atribut pengguna itu dengan notasi titik. Misalnya, current_user.email
, current_user.password
, dan current_user.name
, serta current_user.id
akan memberikan nilai sebenarnya yang disimpan di dalam basis data bagi pengguna yang log masuk.
Mari kita gunakan nama pengguna saat ini dan mengirimkannya ke templat. Kemudian, kita akan menggunakan nama itu dan menampilkan nilainya.
from flask_login import login_required, current_user
...
@main.route('/profile')
@login_required
def profile():
return render_template('profile.html', name=current_user.name)
Lalu, dalam berkas profile.html
, perbarui laman untuk menampilkan nilai name
:
...
<h1 class="title">
Welcome, {{ name }}!
</h1>
Setelah kita mengunjungi laman profil, kita akan melihat bahwa nama pengguna muncul.
Hal terakhir yang dapat kita lakukan adalah memperbarui tampilan log keluar. Kita dapat memanggil fungsi logout_user
dalam suatu rute untuk log keluar. Kita memiliki dekorator @login_required
karena tidak masuk akal untuk mengeluarkan pengguna yang sebelumnya tidak log masuk.
from flask_login import login_user, logout_user, login_required
...
@auth.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('main.index'))
Setelah kita log keluar dan mencoba melihat laman profil lagi, kita melihat pesan kesalahan muncul. Ini karena Flask-Login melakukan flash pesan untuk kita ketika pengguna tidak diizinkan untuk mengakses laman.
Satu hal terakhir yang dapat kita lakukan adalah memasukkan pernyataan if
di dalam templat untuk menampilkan hanya tautan yang relevan dengan pengguna. Jadi, sebelum pengguna log masuk, mereka akan memiliki opsi untuk log masuk atau mendaftar. Setelah mereka log masuk, mereka dapat mengunjungi profil mereka atau log keluar:
...
<div class="navbar-end">
<a href="{{ url_for('main.index') }}" class="navbar-item">
Home
</a>
{% if current_user.is_authenticated %}
<a href="{{ url_for('main.profile') }}" class="navbar-item">
Profile
</a>
{% endif %}
{% if not current_user.is_authenticated %}
<a href="{{ url_for('auth.login') }}" class="navbar-item">
Login
</a>
<a href="{{ url_for('auth.signup') }}" class="navbar-item">
Sign Up
</a>
{% endif %}
{% if current_user.is_authenticated %}
<a href="{{ url_for('auth.logout') }}" class="navbar-item">
Logout
</a>
{% endif %}
</div>
Dengan demikian, Anda telah berhasil membangun aplikasi Anda dengan autentikasi.
Kita telah menggunakan Flask-Login dan Flask-SQLAlchemy untuk membangun sistem log masuk pada aplikasi. Kita telah membahas cara melakukan autentikasi pengguna dengan menciptakan model pengguna dan menyimpan informasi pengguna terlebih dahulu. Kemudian, kita harus memverifikasi bahwa kata sandi pengguna adalah benar dengan melakukan hash kata sandi dari formulir dan membandingkannya dengan yang disimpan di basis data. Terakhir, kita menambahkan otorisasi ke aplikasi kita menggunakan dekorator @login_required
di laman profil sehingga hanya pengguna yang sedang log masuk yang dapat melihat laman itu.
Yang kita ciptakan dalam tutorial ini akan cukup untuk aplikasi yang kecil, tetapi jika Anda ingin memiliki fungsionalitas lebih banyak sejak awal, Anda mungkin dapat mempertimbangkan untuk menggunakan baik pustaka Flask-User atau Flask-Security, yang mana keduanya dibangun di atas pustaka Flask-Login.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!