Django REST framework で API にベーシック認証を実装する

シェアする

Django REST framework で API にベーシック認証を実装します。

外部に公開する API を特定のユーザのみ使わせたい場合があります。特定のユーザのみに使わせたい場合、API にベーシック認証をつける方法を良く見かけるのですが、Django REST framework を使うと簡単に実装することができます。

実装イメージ

環境とバージョン

  • CentOS 7.4
  • Python 3.6.4
  • Django 2.0.3
  • Django REST framework 3.8.2

インストール

Python のインストール

$ sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm
$ sudo yum install -y python36u python36u-libs python36u-devel python36u-pip

Python は IUS リポジトリの Python 3.6 をインストールします。

Django のインストール

$ sudo pip install django

pip で Django をインストールします。

Django REST framework のインストール

$ sudo pip install djangorestframework

pip で Django REST framework をインストールします。

実装

startproject, startapp

$ django-admin startproject api_basic_auth
$ cd api_basic_auth/
$ python3.6 manage.py startapp app

まず最初に、Django のプロジェクトとアプリケーションを作成します。

settings.py

ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
    ...
    'rest_framework',
    'app.apps.AppConfig',
]

settings.py はいつものように、外部からのアクセスを受け付けるようにALLOWED_HOSTS に ‘*’ をセットし、INSTALLED_APPS に Django REST framework と先ほど作成したアプリケーションをセットします。

views.py

from django.contrib.auth.models import User
from rest_framework import viewsets
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from app.serializers import UserSerializer

class UserViewSet(viewsets.ModelViewSet):
    permission_classes = (IsAuthenticated,)
    authentication_classes = (BasicAuthentication,)
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializer

views.py です。ここでベーシック認証の実装を行います。

authentication_classes 変数に BasicAuthentication をセットすることで、この API をベーシック認証にすることができます。

Global setting

上記のやり方は API 毎の実装方法になりますが、プロジェクト全体にベーシック認証を有効にすることもできます。プロジェクト全体にベーシック認証をかけたい場合は、以下を settings.py に追加すれば OK です。

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
    )
}

serializers.py

from django.contrib.auth.models import User
from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = '__all__'

シリアライザは、前回と同じで、Django のユーザ認証用 model を実装しました。

urls.py

from django.urls import path, include
from rest_framework import routers

from app import views

router = routers.DefaultRouter()
router.register('user', views.UserViewSet)

urlpatterns = [
    path('api/', include(router.urls)),
]

urls.py です。API の URL が http://アドレス/api/ になるようにルーティングしました。

tree

$ tree
.
├── api_basic_auth
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── app
│   ├── __init__.py
│   ├── apps.py
│   ├── serializers.py
│   └── views.py
└── manage.py

2 directories, 9 files

ファイル構成はこのようになりました。

動作確認

DB migrate

$ python3.6 manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying sessions.0001_initial... OK

動作確認する前に、DB をセットアップします。settings.py はデフォルトのままですので、sqlite を使用します。

runserver

$ python3.6 manage.py rumserver 0.0.0.0:8000

動作確認するために、Django デバッグサーバ runserver を起動し、ブラウザで、http://IPアドレス:8000/api/user/ にアクセスします。

アクセスすると、ベーシック認証を要求するのが確認できると思います。ここで要求されるユーザとパスワードは、Django のログイン認証のアカウントですので、createsuperuser コマンドなどで作成したアカウントで認証することができます。

まとめ

Django REST framework で API にベーシック認証を実装しました。

ベーシック認証は、自前で実装することもできますが、なかなか面倒です。しかし、Django REST framework で実装すると、簡単に実装できる上に、Django のログイン認証アカウントと連動できるメリットがあります。