2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【簡単】django_restframeworkのjwt認証を最低限実装していく

Posted at

目的

スロットリングの実装は以前に行い、APIを叩く回数に制限をかけることでブルートフォース攻撃などに対策を行なったが、それだけでAPIに関するセキュリティが万全と言えるわけもない。
**なぜなら誰でもAPIを叩ける状態になっているから。**そこでこのAPIを認証されたユーザーだけが制限された回数叩けるように認証周りを実装していきたい。

実施環境

ハードウェア環境

項目 情報
OS macOS Catalina(10.15.7)
ハードウェア MacBook Air (11-inch, Early 2015)
プロセッサ 1.6 GHz デュアルコアIntel Core i5
メモリ 4 GB 1600 MHz DDR3
グラフィックス intel HD Graphics 6000 1536 MB

ソフトウェア環境

項目 情報
homebrew 3.3.8
mysql Ver 8.0.27 for macos10.15 on x86_64
python 3.8.12
anaconda 4.10.1
django 21.2.4
pip 3.1.2

概要

usernameとpasswordでaccess_tokenを発行する時にはrefresh_tokenも同時に発行され、フロントのlocalStorageやCookieに保存される。
access_tokenの有効期限が切れている場合には、フロントのlocalStorageやCookieから有効期限がaccess_tokenよりも長いrefresh_tokenを利用してもう一度access_tokenを発行することができる

JWTトークンを取得する

###「Django REST framework JWT」インストール

$ pip install djangorestframework-simplejwt==4.6.*

setting.pyに設定を追加する

ACCESS_TOKEN_LIFETIMEはAuthトークンの有効期限を自分で好きな時間に変更する。

settings.py
REST_FRAMEWORK = {
    # jwtトークン認証
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),  
}
SIMPLE_JWT = {
    'AUTH_HEADER_TYPES': ('JWT'),
    # JWT有効期限
    'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30),
}

設定ディレクトリのurls.pyにエンドポイントを実装する

simplejwtライブラリに入っているTokenObtainPairViewとTokenRefreshViewへのルーティングを実装

urls.py
from django.contrib import admin
from django.db import router
from django.urls import path, include
from rest_framework_simplejwt import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/v1/', include('tinder.urls')),
    # jwt-tokenを取得
    path('api-auth/jwt/', views.TokenObtainPairView.as_view()),
    # jwt-tokenを再取得
    path('api-auth/jwt/refresh', views.TokenRefreshView.as_view()),
]

postmanやcurlコマンドでAPIを叩く

画像のように、上記で実装したurls.pyのAPIエンドポイントを叩くと
※ トークンを取得するが、POSTメソッドでなければ許可されないため注意
※ usernameとpasswordをBodyに含める必要がある。

スクリーンショット 2021-12-27 午後6.52.49.png

実際にJWT認証をViews.pyに適用する

下記のように指定のViewsの認証を追加する

views.py
from rest_framework.permissions import IsAuthenticated

class MemberViewSet(viewsets.ModelViewSet):
    queryset = Members.objects.all()
    serializer_class = MemberSerializer
    # 今回の追加部分
    permission_classes = (IsAuthenticated,)

viewごとにpermission_classesでどのような制限をかけるかを指定できる。
今回はMemberViewSetを利用できるのはログイン認証ができているユーザーのみ。
つまり、headerのAuthorizationに先ほど取得したaccess_tokenを入れてAPIエンドポイントを叩いた場合のみAPIを利用できる。
permission_classes = (IsAuthenticated,)この部分で,がないとエラーになるため要注意

access_tokenをHeaderに含めていない状態

認証状態が含まれていないと指摘される。
無事にこのAPIを叩くにはaccess_tokenが必要になったようだ

{
    "detail": "認証情報が含まれていません。"
}

スクリーンショット 2021-12-27 午後7.30.55.png

access_tokenをHeaderに含めた状態

headersのAuthorizationに先ほど取得したaccess_tokenを入れてもう一度APIを叩いてみる。

スクリーンショット 2021-12-27 午後7.30.38.png

無事JSONデータを取得できた。

参考文献

「Django REST framework JWT」でAPI認証を行う

Django REST framework に JWTログイン機能を実装する

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?