Django Rest Framework JWT を使ってアカウント管理しよう！

![django_rest_framework.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659561/cea49f61-5bf1-d065-81b2-5a2e007eb176.jpeg)


# はじめに

最近、BackendのAPIを作るところはDjangoで作ってみることが多く、その中で認証するのですが、
Django Rest Framework JWT というのが使いやすかったので、紹介します。

Django Rest Framework JWT というのは、名前の通り Django Rest Framework でサポートされているので、
簡単に組み込むことができるかと思います。

# 環境

Python - 3.8.6
Django - 3.1.4


# 最小限の始め方

## Django アプリケーションを作成

```
$  pip install djangorestframework-jwt
$ django-admin startproject mysite
$ python manage.py startapp polls
```

## 設定ファイルを編集

```python:settings.py
REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',”
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.BasicAuthentication',
    ),
}
```

```python:urls.py
from django.contrib import admin
from django.urls import path
from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api-token-auth/', obtain_jwt_token),
]
```

## データベースのマイグレート

```
$ python manage.py makemigrations
$ python manage.py migrate
# 例としてパスワードは「password123」
$ python manage.py createsuperuser --username admin --email ""
```

## Django アプリケーションの起動

```
$ python manage.py runserver
```

## トークンの発行

```
$ curl -X POST -d "username=admin&password=password123" http://localhost:8000/api-token-auth/
```

戻り値の "token" の値部分がトークンになります。

## トークンで認証を突破する

```python
# -*- coding: utf-8 -*-

from rest_framework.response import Response
from rest_framework.status import HTTP_200_OK, HTTP_401_UNAUTHORIZED
from rest_framework.views import APIView

from app.api.types import Request


class UserApi(APIView):
    def get(self, request: Request) -> Response:
        if not request.user.is_authenticated:
            return Response(status=HTTP_401_UNAUTHORIZED)

        response = {'username': request.user.username}
        return Response(response, status=HTTP_200_OK)
```

こんな感じのエントリポイントを作ったとします。

そこに対して、

```
$ curl -H "Authorization: JWT <your_token>" http://localhost:8000/user/
```

のようにリクエストすることで認証を行い、エントリポイントへのリクエストが可能となります。

# トークンのリセット

## 設定ファイルを編集

```python:urls.py
from django.contrib import admin
from django.urls import path
from rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api-token-auth/', obtain_jwt_token),
    path('api-token-refresh/', refresh_jwt_token),
]
```

## トークンをリセットする

```
$ curl -X POST -H "Content-Type: application/json" -d '{"token":"<EXISTING_TOKEN>"}' http://localhost:8000/api-token-refresh/
```

# トークンのチェック

## 設定ファイルを編集

```python:urls.py
from django.contrib import admin
from django.urls import path
from rest_framework_jwt.views import obtain_jwt_token, refresh_jwt_token, verify_jwt_token

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api-token-auth/', obtain_jwt_token),
    path('api-token-refresh/', refresh_jwt_token),
    path('api-token-verify/', verify_jwt_token),
]
```

## トークンをチェックする

```
$ curl -X POST -H "Content-Type: application/json" -d '{"token":"<EXISTING_TOKEN>"}' http://localhost:8000/api-token-verify/
```

# おわりに

いかがでしたか？
実際に試さなくても理解できるくらいシンプルな作りかと思います。

ほかにも細かな設定は可能ですが、その辺りは、[こちら](https://jpadilla.github.io/django-rest-framework-jwt/#additional-settings)をご確認ください。

もっと良いアカウント管理方法などありましたら、ぜひ教えてください！

https://note.com/ryoka_in
こちらのサイトで一部の記事を先行して有料公開しています。ぜひご覧ください。

# 参考

https://jpadilla.github.io/django-rest-framework-jwt/