Django REST framework で API にベーシック認証を実装します。
外部に公開する API を特定のユーザのみ使わせたい場合があります。特定のユーザのみに使わせたい場合、API にベーシック認証をつける方法を良く見かけるのですが、Django REST framework を使うと簡単に実装することができます。
Contents
実装イメージ
環境とバージョン
- 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 のログイン認証アカウントと連動できるメリットがあります。