JWT trong django rest framework
This post hasn't been updated for 5 years
Trong bài viết này mình sẽ hướng dẫn các bạn sử dụng JWT
làm phương thức login trong django rest framwork
.
Requirements
Giả sử máy bạn đã cài sẵn các package và thư viện cần thiết sau:
- Python (3.6, 3.7)
- Django (2.0, 2.1, 2.2)
- Django REST Framework (3.8, 3.9, 3.10)
Cài đặt
pip install djangorestframework_simplejwt
Trong file setting.py
thay đổi như sau:
REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': (
...
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
...
}
Trong file urls.py
thêm vào đoạn code sau:
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
urlpatterns = [
...
url(r'^api/token/$', TokenObtainPairView.as_view(), name='token_obtain_pair'),
url(r'^api/token/refresh/$', TokenRefreshView.as_view(), name='token_refresh'),
...
]
Sử dụng
Để lấy login sử dụng api sau: http://localhost:8000/api/token/
:
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"username": "davidattenborough", "password": "boatymcboatface"}' \
http://localhost:8000/api/token/
.....
{
"access":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNDU2LCJqdGkiOiJmZDJmOWQ1ZTFhN2M0MmU4OTQ5MzVlMzYyYmNhOGJjYSJ9.NHlztMGER7UADHZJlxNG0WSi22a2KaYSfd1S-AuT7lU",
"refresh":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImNvbGRfc3R1ZmYiOiLimIMiLCJleHAiOjIzNDU2NywianRpIjoiZGUxMmY0ZTY3MDY4NDI3ODg5ZjE1YWMyNzcwZGEwNTEifQ.aEoAYkSJjoWH1boshQAaTkf8G3yn0kapko6HFRt7Rh4"
}
sau khi login thành công, chúng ta có được access token và refresh token
Để sử dụng token:
Bạn sử dụng token đã lấy được ở phần login để gọi bất kỳ api nào:
curl \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNDU2LCJqdGkiOiJmZDJmOWQ1ZTFhN2M0MmU4OTQ5MzVlMzYyYmNhOGJjYSJ9.NHlztMGER7UADHZJlxNG0WSi22a2KaYSfd1S-AuT7lU" \
http://localhost:8000/api/me/
Refresh token
token
sẽ có thời gian sống ngắn hơn refresh token
, nên khi token hết bạn jwt cung cấp cho chúng ta api refresh token
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"refresh":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImNvbGRfc3R1ZmYiOiLimIMiLCJleHAiOjIzNDU2NywianRpIjoiZGUxMmY0ZTY3MDY4NDI3ODg5ZjE1YWMyNzcwZGEwNTEifQ.aEoAYkSJjoWH1boshQAaTkf8G3yn0kapko6HFRt7Rh4"}' \
http://localhost:8000/api/token/refresh/
....
{"access":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNTY3LCJqdGkiOiJjNzE4ZTVkNjgzZWQ0NTQyYTU0NWJkM2VmMGI0ZGQ0ZSJ9.ekxRxgb9OKmHkfy-zs1Ro_xs1eMLXiR17dIDBVxeT-w"}
Settings
Thư viện này có khá nhiều tùy chọn, sau đây mình sẽ cung cấp một số tùy chọn để các bạn thay đổi config nếu muốn:
# Django project settings.py
from datetime import timedelta
...
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'ALGORITHM': 'HS256',
'SIGNING_KEY': settings.SECRET_KEY,
'VERIFYING_KEY': None,
'AUTH_HEADER_TYPES': ('Bearer',),
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}
ACCESS_TOKEN_LIFETIME
: thời gian sống của token
REFRESH_TOKEN_LIFETIME
: thời gian sống của refresh token
AUTH_HEADER_TYPES
: header type, chính là cái chữBearer
khi các bạn sử dụng token để gọi lên server lấy dữ liệu
Mình chỉ thay đổi 3 config này, còn lại sử dụng mặc định của nó hêt, nếu các bạn muốn xem thêm config có thể vào đây để xem thêm: https://github.com/davesque/django-rest-framework-simplejwt
Customizing token
Thư viện cũng cung cấp một số function giúp chúng ta customizing cách tạo ra token, thêm thông tin vào token trả ra ...
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super().get_token(user)
# thêm thôn tin bạn muôn
token['name'] = user.name
# ...
return token
class MyTokenObtainPairView(TokenObtainPairView):
serializer_class = MyTokenObtainPairSerializer
hay tạo 1 token qua api:
from rest_framework_simplejwt.tokens import RefreshToken
def get_tokens_for_user(user):
refresh = RefreshToken.for_user(user)
return {
'refresh': str(refresh),
'access': str(refresh.access_token),
}
Tham khảo
All Rights Reserved