LoginSignup
1
0

More than 3 years have passed since last update.

djangorestframework-jwtでユーザー認証とトークン認証を簡単で実現する

Last updated at Posted at 2020-10-27

中国の開発者です。東京浜松町で1年ぐらい働いたことがありました。どうぞよろしくお願いします。

djangorestframework-jwtの紹介

djangorestframework-jwtはDjangoのパッケージとして、ユーザー認証とトークン認証が簡単で実現できます。

この記事はdjangorestframework-jwtを使ってAPIの作る方法を伝えます。

環境
OS:Win10 or CentOS
Python:3.7
Django:3.1.2

インストール

この二つのライリブラリが必要です。

$ pip install djangorestframework

$ pip install djangorestframework-jwt

コーティング

①これらのコードをsettings.pyに改修、或は追加する

settings.py
import datetime

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',  # <-- 追加する
    'my_app'
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    # 'django.middleware.csrf.CsrfViewMiddleware',  <-- コメントする
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

# 認証用のフレームワーク
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated'
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication'
    )
}

JWT_AUTH = {
    # トークンの有効時間を設定する
    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=60 * 60 * 2)
}

②urls.pyにコードを挿入する

ここには2つのAPIがあります。

  1. userLoginはユーザー登録認証用APIです。フロントエンドはPOSTでユーザー名とパスワードをバックエンドに送って、登録してから、トークンを取得するAPIです。(ユーザーとパスワードはdjango adminのスーパーユーザーを使っていいです。)

  2. getInfoはユーザー登録後、トークンを使って情報を取得するAPIです。

urls.py
from django.urls import path
from my_app import views

urlpatterns = [
    path('userLogin/', views.user_login),
    path('getInfo/', views.get_info)
]

③views.pyにコードを挿入する

views.py
import json
from django.http import JsonResponse
from django.contrib.auth import authenticate, login
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework_jwt.settings import api_settings


def user_login(request):
    obj = json.loads(request.body)
    username = obj.get('username', None)
    password = obj.get('password', None)

    if username is None or password is None:
        return JsonResponse({'code': 500, 'message': '请求参数错误'})

    is_login = authenticate(request, username=username, password=password)
    if is_login is None:
        return JsonResponse({'code': 500, 'message': '账号或密码错误'})

    login(request, is_login)

    jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
    jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
    payload = jwt_payload_handler(is_login)
    token = jwt_encode_handler(payload)

    return JsonResponse(
        {
            'code': 200,
            'message': '登録成功',
            'data': {'token': token}
        }
    )


# APIにトークン認証を付与する
@api_view(['GET'])
@permission_classes((IsAuthenticated,))
@authentication_classes((JSONWebTokenAuthentication,))
def get_info(request):
    data = 'some info'

    return JsonResponse(
        {
            'code': 200,
            'message': 'success',
            'data': data
        }
    )

フロントエンドはAPIをどう使用する

まず、POSTでuserLoginを使用して、トークンを取得する。

次、GetでgetInfoを使用して、HeadersのAuthorizationパラメータにJWT + 先ほど取得したトークンを指定してリクエストする。

フロントエンドの例
token = 'abcdefg123456789'

authorization = 'JWT' + token

こうすると、getInfoはリクエストできます。

1
0
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
1
0