Token Web JSON mudah digunakan dan di-debug, tetapi juga menawarkan peningkatan keamanan yang mengesankan.

Otentikasi yang rusak terus menjadi kerentanan yang terus-menerus dalam aplikasi web modern—masih berperingkat tinggi dalam 10 risiko keamanan API teratas OWASP.

Efek dari kerentanan ini bisa parah. Mereka dapat memberikan akses tidak sah ke data sensitif dan mengganggu integritas sistem. Untuk memastikan akses yang aman ke aplikasi dan sumber dayanya secara efektif, Anda harus menggunakan mekanisme autentikasi yang kuat.

Cari tahu bagaimana Anda bisa mengimplementasikan autentikasi pengguna di Flask menggunakan JSON Web Tokens (JWT), metode berbasis token yang populer dan efektif.

Otentikasi Berbasis Token Menggunakan Token Web JSON

Otentikasi berbasis token menggunakan string karakter terenkripsi untuk memvalidasi dan mengotorisasi akses ke sistem atau sumber daya. Anda dapat mengimplementasikan jenis autentikasi ini menggunakan berbagai metode, termasuk token sesi, kunci API, dan Token Web JSON.

JWT, khususnya, menawarkan pendekatan yang aman dan kompak untuk mentransmisikan kredensial pengguna yang diperlukan antara aplikasi sisi klien dan server.

JWT terdiri dari tiga komponen utama: header, payload, dan tanda tangan. Header berisi metadata tentang token, termasuk algoritme hashing yang digunakan untuk menyandikan token.

Muatan berisi kredensial pengguna yang sebenarnya, seperti ID pengguna dan izin. Terakhir, tanda tangan memastikan validitas token dengan memverifikasi isinya menggunakan kunci rahasia.

Dengan menggunakan JWT, Anda dapat mengautentikasi pengguna dan menyimpan data sesi di dalam token itu sendiri.

Menyiapkan Proyek Flask dan Database MongoDB

Untuk memulai, buat direktori proyek baru menggunakan terminal:

proyek termos mkdir
cd flask-proyek

Selanjutnya, instal virtualenv, untuk membuat lingkungan pengembangan virtual lokal untuk proyek Flask Anda.

virtualenv venv

Terakhir, aktifkan lingkungan virtual.

# Unix atau MacOS: 
sumber venv/bin/aktifkan

# Jendela:
.\venv\Scripts\aktifkan

Anda dapat menemukan kode proyek ini di sini repositori GitHub.

Instal Paket yang Diperlukan

Di direktori root folder proyek Anda, buat yang baru persyaratan.txt file, dan tambahkan dependensi ini untuk proyek:

labu
pyjwt
python-dotenv
pymongo
bcrypt

Terakhir, jalankan perintah di bawah ini untuk menginstal paket. Pastikan Anda memilikinya pip (manajer paket) terpasang; jika tidak, instal di sistem Windows, Mac, atau Linux Anda.

pip instal -r persyaratan.txt

Buat Database MongoDB

Lanjutkan dan buat database MongoDB. Kamu bisa mengatur database MongoDB lokal, kalau tidak, buat cluster di MongoDB Atlas, layanan MongoDB berbasis cloud.

Setelah Anda membuat database, salin URI koneksi, buat file .env file di direktori root proyek Anda, dan tambahkan sebagai berikut:

MONGO_URI=""

Terakhir, konfigurasikan koneksi database dari aplikasi Flask Anda. Buat yang baru utils/db.py file di direktori root proyek Anda, dengan kode ini:

dari pymongo impor Klien Mongo

defconnect_to_mongodb(mongo_uri):
klien = MongoClient (mongo_uri)
db = client.get_database("pengguna")
kembali db

Fungsi ini membuat koneksi ke database MongoDB menggunakan URI koneksi yang disediakan. Itu kemudian menciptakan yang baru pengguna koleksi jika tidak ada, dan mengembalikan instance database yang sesuai.

Buat Server Web Flask

Dengan database yang dikonfigurasi, lanjutkan, dan buat file app.py file di direktori root folder proyek, dan tambahkan kode berikut untuk membuat instance aplikasi Flask.

dari labu impor Labu
dari rute.pengguna_auth impor daftar_rute
dari utils.db impor connect_to_mongodb
impor os
dari dotenv impor load_dotenv

aplikasi = Labu (__nama__)
load_dotenv()

mongo_uri = os.getenv('MONGO_URI')
db = sambungkan_ke_mongodb (mongo_uri)

register_routes (aplikasi, db)

jika __nama__ == '__utama__':
aplikasi.jalankan (debug=BENAR)

Buat Titik Akhir API Otentikasi

Untuk menerapkan autentikasi pengguna di aplikasi Flask Anda, sangat penting untuk menentukan titik akhir API yang diperlukan yang menangani operasi terkait autentikasi.

Namun, pertama-tama, tentukan model untuk data pengguna. Untuk melakukannya, buat yang baru model/user_model.py file di direktori root, dan tambahkan kode berikut.

dari pymongo.collection impor Koleksi
dari bson.objectid impor ObjectId

kelasPengguna:
def__init__(self, koleksi: Koleksi, nama pengguna: str, kata sandi: str):
self.collection = koleksi
self.username = nama pengguna
self.password = kata sandi
defmenyimpan(diri sendiri):
data_pengguna = {
'nama belakang': self.namapengguna,
'kata sandi': self.password
}
hasil = self.collection.insert_one (user_data)
kembali str (hasil.dimasukkan_id)

@metode statis
deffind_by_id(koleksi: Koleksi, user_id: str):
kembali koleksi.temukan_satu({'_pengenal': ObjectId (user_id)})

@metode statis
deffind_by_username(koleksi: Koleksi, nama pengguna: str):
kembali koleksi.temukan_satu({'nama belakang': nama belakang})

Kode di atas menentukan a Pengguna kelas yang berfungsi sebagai model data dan mendefinisikan beberapa metode untuk berinteraksi dengan koleksi MongoDB untuk melakukan operasi terkait pengguna.

  1. Itu menyimpan metode menyimpan dokumen pengguna baru dengan nama pengguna dan kata sandi yang disediakan ke koleksi MongoDB dan mengembalikan ID dari dokumen yang dimasukkan.
  2. Itu find_by_id Dan find_by_username metode mengambil dokumen pengguna dari koleksi masing-masing berdasarkan ID pengguna atau nama pengguna yang disediakan.

Tentukan Rute Otentikasi

  1. Mari kita mulai dengan menentukan rute pendaftaran. Rute ini akan menambahkan data pengguna baru ke koleksi pengguna MongoDB. Di direktori root, buat yang baru rute/user_auth.py file, dan kode berikut.
    impor jwt
    dari functools impor membungkus
    dari labu impor jsonify, permintaan, make_response
    dari model.user_model impor Pengguna
    impor bcrypt
    impor os

    defdaftar_rute(aplikasi, db):
    koleksi = db.pengguna
    aplikasi.config['KUNCI RAHASIA'] = os.urandom(24)

    @ app.route('/api/register', methods=['POST'])
    defdaftar():

    nama pengguna = permintaan.json.get('nama belakang')
    kata sandi = permintaan.json.get('kata sandi')

    existing_user = User.find_by_username (koleksi, nama pengguna)
    jika pengguna_yang ada:
    kembali jsonify({'pesan': 'Nama pengguna sudah ada!'})

    hashed_password = bcrypt.hashpw (password.encode('utf-8'), bcrypt.gensalt())
    new_user = Pengguna (koleksi, nama pengguna, hashed_password.decode('utf-8'))
    user_id = new_user.save()

    kembali jsonify({'pesan': 'Pengguna berhasil terdaftar!', 'identitas pengguna': identitas pengguna})

  2. Menerapkan fungsionalitas login, untuk menangani proses autentikasi dan memverifikasi kredensial pengguna. Di bawah rute pendaftaran, tambahkan kode berikut.
     @ aplikasi.route('/api/login', metode=['POST'])
    defGabung():
    nama pengguna = permintaan.json.get('nama belakang')
    kata sandi = permintaan.json.get('kata sandi')
    user = User.find_by_username (koleksi, nama pengguna)
    jika pengguna:
    jika bcrypt.checkpw (password.encode('utf-8'), pengguna['kata sandi'].menyandi('utf-8')):
    token = jwt.kodekan({'identitas pengguna': str (pengguna['_pengenal'])}, app.config['KUNCI RAHASIA'], algoritma='HS256')

    respon = make_response (jsonify({'pesan': 'Login berhasil!'}))
    respon.set_cookie('token', token)
    kembali tanggapan

    kembali jsonify({'pesan': 'Username dan password salah'})

    Endpoint login melakukan dua hal: memverifikasi kredensial pengguna yang disediakan dan, setelah autentikasi berhasil, menghasilkan JWT unik untuk pengguna tersebut. Ini menyetel token ini sebagai cookie dalam respons, bersama dengan muatan JSON yang menunjukkan proses masuk yang berhasil. Jika kredensial tidak valid, respons JSON akan dikembalikan untuk menunjukkannya.
  3. Tentukan fungsi dekorator yang memverifikasi Token Web JSON (JWT) yang diteruskan bersama dengan permintaan API berikutnya. Tambahkan kode di bawah ini di dalam daftar_rute blok kode fungsi.
    deftoken_required(F):
    @bungkus (f)
    defdihiasi(*args, **kwargs):
    token = permintaan.cookies.get('token')

    jikabukan token:
    kembali jsonify({'pesan': 'Token hilang!'}), 401

    mencoba:
    data = jwt.decode (token, app.config['KUNCI RAHASIA'], algoritma=['HS256'])
    current_user = Pengguna.find_by_id (koleksi, data['identitas pengguna'])
    kecuali jwt. ExpiredSignatureKesalahan:
    kembali jsonify({'pesan': 'Token telah kedaluwarsa!'}), 401
    kecuali jwt. InvalidTokenError:
    kembali jsonify({'pesan': 'Token tidak valid!'}), 401

    kembali f (pengguna_saat ini, *args, **kwargs)

    kembali dihiasi

    Fungsi dekorator ini memastikan keberadaan token JWT yang valid dalam permintaan API selanjutnya. Ini memeriksa apakah token hilang, kedaluwarsa, atau valid, dan mengembalikan respons JSON yang sesuai jika memang demikian.
  4. Terakhir, buat rute yang dilindungi.
     @app.route('/api/pengguna', metode=['GET'])
    @token_required
    defget_users(pengguna_saat ini):
    pengguna = daftar (collection.find({}, {'_pengenal': 0}))
    kembali jsonify (pengguna)

Titik akhir ini menangani logika untuk mengambil data pengguna dari database, tetapi memerlukan permintaan pengiriman klien untuk menyertakan token yang valid untuk mengakses data.

Terakhir, jalankan perintah di bawah ini untuk mengaktifkan server pengembangan.

menjalankan labu

Untuk menguji registrasi, login, dan titik akhir pengguna yang dilindungi, Anda dapat menggunakan Postman atau klien API lainnya. Kirim permintaan ke http://localhost: 5000/api/dan amati respons untuk memverifikasi fungsionalitas titik akhir API ini.

Apakah Otentikasi Token Merupakan Tindakan Keamanan yang Sangat Mudah?

Token Web JSON memberikan cara yang kuat dan efektif untuk mengautentikasi pengguna untuk aplikasi web Anda. Namun, penting untuk dipahami bahwa autentikasi token tidaklah mudah; itu hanya satu bagian dari teka-teki keamanan yang lebih besar.

Gabungkan autentikasi token dengan praktik terbaik keamanan lainnya. Ingatlah untuk terus memantau, dan menerapkan praktik keamanan yang konsisten; Anda akan secara signifikan meningkatkan keamanan keseluruhan aplikasi Flask Anda.