Tutorial RESTful API dengan Flask Python Part 7— Middleware API dengan JWT (JSON Web Token)

Membuat Autentikasi API dengan JWT di Flask Python

Hudya
6 min readFeb 22, 2020

Hello fellas, kembali lagi bersama Kiddy. Pada artikel kali ini saya mau berbagi insight mengenai cara membuat validasi API dengan JWT (Json Web Token).

Saya ngga perlu bahas-bahas apa itu JWT lagi ya, kalo agan membaca thread ini saya anggap agan udah paham apa itu JWT.

Nah pada tutorial kali ini, saya akan menggunakan salah satu library Flask JWT Extended.

Ohiya di tutorial ini saya pake project saya yang ini ya, apabila agan belom ada silahkan aja clone dari sini.

Oke kalo semua udah siap, start coding kita!

Pertama, jangan lupa aktivasi virtualenv nya dulu

Kedua, install library-nya dengan cara

pip install flask-jwt-extended

Ketiga, __init__.py kita mesti dimodif sedikit dulu untuk inisialisasi JWT-nya.

from flask_jwt_extended import JWTManager #Inisialisasi JWT

Perhatikan kode dibawah:

app = Flask(__name__)
app.config.from_object(Config)

Setelah import, kita perlu menuliskan kode inisialisasinya, silahkan copy paste kode dibawah ini, dan paste letaknya dibawah kedua kode diatas.

jwt = JWTManager(app)

Kira-kira kaya gini lah:

Sekarang buka file config.py di root folder kita dan tambahin satu value baru.

JWT_SECRET_KEY = str(os.environ.get("JWT_SECRET"))

Fungsinya akan menjadi JWT Secret Key kita, bisa apa aja, umumnya sih 32/64 random string (alphanumeric, dan simbol).

Sekarang tambahin keynya di .flaskenv

JWT_SECRET=xxxxxx

Sekarang method login kita perlu diubah sedikit. Yuk diubah dulu biar bisa generate token.

def login():
try:
email = request.json['email']
password = request.json['password']

user = Users.query.filter_by(email=email).first()
if not user:
return response.badRequest([], 'Empty....')

if not user.checkPassword(password):
return response.badRequest([], 'Your credentials is invalid')

data = singleTransform(user, withTodo=False)
expires = datetime.timedelta(days=1)
expires_refresh = datetime.timedelta(days=3)
access_token = create_access_token(data, fresh=True, expires_delta=expires)
refresh_token = create_refresh_token(data, expires_delta=expires_refresh)

return response.ok({
"data": data,
"token_access": access_token,
"token_refresh": refresh_token,
}, "")
except Exception as e:
print(e)

Oke kita bisa liat ada dua parameter tambahan di create_access_token, yang pertama ada fresh, dan yang kedua ada expires_delta.

fresh adalah parameter yang nandain bahwa token ini baru dan metode ini kita verifikasi melalui username dan password yang dimasukkan.

    # create_access_token supports an optional 'fresh' argument,
# which marks the token as fresh or non-fresh accordingly.
# As we just verified their username and password, we are
# going to mark the token as fresh here.

Ini kata dokumentasi librarynya.

expires_delta adalah waktu expired tokennya dalam waktu delta, default library ini adalah 15 menit, kecil banget kan? Nah makanya kita perpanjang aja jadi 1 hari, kalian bisa ubah days=1 menjadi minutes=60, bahkan hours=2 kok, bisa diubah sesuai kebutuhan API kalian.

Sekarang masuk ke TodoController.py dan coba ubah sedikit method indexnya.

from flask_jwt_extended import *


@jwt_required
def index():
try:
id = request.args.get('user_id')
todo = Todo.query.filter_by(user_id=id).all()
data = transform(todo)
return response.ok(data, "")
except Exception as e:
print(e)

Kita akan memberikan decorators pada method tersebut, apa itu decorators? Nanti aja ya saya jelasin apa itu dan cara buat customnya. Dengan decorators @jwt_required kita jadi ngebuat method tersebut membutuhkan JWT sebelum diakses.

Sekarang kita coba dulu yuk.

Nah liat, ada error Missing Authorization Header, artinya saya ngga masukin header yang isinya “Authorization”, sekarang kita coba masukin.Oke karena kita belom punya tokennya, kita generate dulu yuk.

Nah disini kita bisa liat ada dua data, token_access, dan token_refresh, token_access digunakan untuk ngeakses api kita, sedangkan token_refresh digunakan untuk merefresh token kita yang udah expired nantinya.

Sekarang ayo kita coba akses ke API Todo.

Kita perlu menambahkan parameter di Header yaitu Authorization dengan format isi “Bearer <token>”, yang pernah pake JWT pasti paham standar format JWT.

Nah disini saya berhasil karena telah menggunakan token, kalo misalnya tidak menggunakan Authorization pasti akan error seperti error pertama.

Nah ini yang terjadi kalo tokennya expired.

Salah satu teknik untuk merefresh token tanpa melakukan validasi ulang (Login ulang) adalah menggunakan endpoint refresh, kita wajib buat dulu.

@jwt_refresh_token_required
def refresh():
try:
user = get_jwt_identity()
new_token = create_access_token(identity=user, fresh=False)

return response.ok({
"token_access": new_token
}, "")

except Exception as e:
print(e)

Disini kita buat parameter fresh menjadi false, karena ya ini kan ngga pake autentikasi ulang hehehe. Bisa juga dibuat True kok, bedanya akan saya jelaskan dibawah dengan decorators yang tersedia di library bawaan.

Jangan lupa tambahkan parameter baru di routes.

@app.route('/refresh', methods=['POST'])
def refresh():
return UserController.refresh()

Masih inget token dari token_refresh kan? nah route /refresh hanya bisa diakses dengan token refresh, jadi jangan coba-coba pake token_access, karena bakalan error. 😆

Caranya juga sama aja kaya akses route lainnya, cukup ganti Authorization dengan token_refresh kita. Jangan lupa formatnya juga tetep “Bearer <token>”

Nah ini setelah berhasil, gampang banget kan?

Oke sekarang kita bahas beberapa decorators bawaan JWT Flask Extended yang tersedia

@jwt_required = Semua token access JWT baik fresh atau tidak bisa diakses.
@fresh_jwt_required = Hanya token access JWT yang fresh aja yang boleh akses.
@jwt_refresh_token_required = Hanya token refresh JWT yang bisa akses ini.

Tinggal disesuaikan aja sama kebutuhanmu!

Q: Bang kapan biasanya token di refresh?
A: Kalo tekniknya di mobile sih biasanya dilakukan dengan cara diproses pada saat splash screen, makanya kadang suka lama atau ada teks “Menyiapkan…” “Authorizing…” dan sebagainya kan, karena sebenernya mereka ngecek akses dari user, bener ngga sih tokennya masih aktif, kalo ngga aktif ya akan direfresh

Q: Bang kenapa token harus di refresh? Kan bisa Autentikasi ulang?
A: Betul, hal paling gampang ya tinggal autentikasi ulang aja malih, tapi bagi startup kecil yang servernya aja kecil perlu dipertimbangkan kembali mengenai route Login yang dihit terus-menerus karena process SELECT ke database kan juga makan RAM dan CPU, jadi daripada nyuruh database kerja lagi mending dari sisi aplikasi aja yang kerja, kita ngurangin beban di database. Sehingga kita bisa tetep ngasih akses tanpa perlu autentikasi ulang.

Q: Bang idealnya token itu berapa lama expired?
A: Tergantung kesepakatan sih, saya biasanya buat sehari, tapi ada baiknya expired itu sekecil mungkin untuk mencegah man in the middle yang menggunakan token orang lain untuk ngakses API kita, ntar malah amsyong loh orang tersebut yang harusnya ngga salah jadi salah wkwkwk. Kaya bank aja biasanya cuma 5 menit kan, biar kesempatannya kecil pas ngebajak. CMIIW!

Oke sampe sini aja ya tutorial kali ini, hepi coding!

Kalo ada yang mau clone juga boleh, udah saya update loh!

--

--

Hudya
Hudya

Written by Hudya

Which is more difficult, coding or counting? Not both of them, the difficult one is sharing your knowledge to people without asking the payment.

No responses yet