DjangoでJWTを使ったトークン認証を実装する
スポンサーリンク
JWT とは
Json Web Token の略。一言でいってしまうとJSONに署名したもの。こちらの記事で詳しく解説されています。
はじめに
さっそく環境を作っていきます。最初はお決まりのプロジェクト作成です。
詳しい手順と説明はこちらの記事をご参照ください。
- 作者: Julia Elman,Mark Lavin
- 出版社/メーカー: O'Reilly Media
- 発売日: 2014/11/04
- メディア: Kindle版
- この商品を含むブログを見る
ではプロジェクトを作成します。
$ django-admin startproject racchai
$ cd racchai
今回は認証を扱うので、データベースとユーザーも作成しておきます。
$ ./manage.py migrate │ Operations to perform: │ Synchronize unmigrated apps: staticfiles, messages │ Apply all migrations: admin, contenttypes, auth, sessions │ Synchronizing apps without migrations: │ Creating tables... │ Running deferred SQL... │ Installing custom SQL... │ Running migrations: │ Rendering model states... DONE │ Applying contenttypes.0001_initial... OK │ Applying auth.0001_initial... OK │ Applying admin.0001_initial... 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 sessions.0001_initial... OK $ ./manage.py createsuperuser Username (leave blank to use 'kon'): racchai Email address: jwt@racchai.com Password: racchai Password (again): racchai Superuser created successfully.
何度やっても楽ちんですね。
トークンを取得してみる
今回は django-rest-framework-jwt を使うのでインストールしておきます。
$ pip install djangorestframework-jwt
インストールができたらracchai/settings.py に以下を追記します。
REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', ), 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', ), 'NON_FIELD_ERRORS_KEY': 'detail', 'TEST_REQUEST_DEFAULT_FORMAT': 'json' }
お次は racchai/urls.py を以下のように編集。
+ from rest_framework_jwt.views import obtain_jwt_token urlpatterns = [ + url(r'^jwt-token', obtain_jwt_token), ]
基本設定は以上です。あっという間ですね。では開発サーバーを起動してトークンを取得してみましょう。
$ ./manage.py runserver $ curl http://localhost:8000/jwt-token -d "username=racchai&password=racchai" {"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InJhY2NoYWkiLCJ1c2VyX2lkIjoxLCJlbWFpbCI6Imp3dEByYWNjaGFpLmNvbSIsImV4cCI6MTQ2MTY1MzY0N30.UBZrYz79xeI25-Uufmh2zdwZXXzHjamh9rHeOS2Fuqk"}
無事取得できました。簡単すぎて本当に動いてるのか疑いたくなりますね。念のためパスワードを間違えてみましょう。
$ curl http://localhost:8000/jwt-token -d "username=racchai&password=jwt" {"detail":["Unable to login with provided credentials."]}
ちゃんと認証失敗しました。安心してください、動いてます。
トークンを使って認証が必要なAPIを実行してみる
まずは認証が必要なAPIを用意します。django-rest-framework-jwt を使っているのですから、APIも django-rest-framework で作ることにします。
django-rest-framework の初期設定についてはこちらの記事で紹介しています。
次は、ログインユーザー名で返事するだけのAPIを作成しましょう。
racchai/views.py
from rest_framework.generics import GenericAPIView from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework import status class PingViewSet(GenericAPIView): permission_classes = (IsAuthenticated,) def get(self, request, format=None): return Response(data={'username': request.user.username}, status=status.HTTP_200_OK)
APIが作成できたら racchai/urls.py
を以下のように編集します。
from django.conf.urls import url from rest_framework_jwt.views import obtain_jwt_token + from racchai import views urlpatterns = [ url(r'^jwt-token', obtain_jwt_token), + url(r'^ping', views.PingViewSet.as_view()), ]
準備ができたら作成したAPIにアクセスしてみましょう。
$ curl http://localhost:8000/ping {"detail":"Authentication credentials were not provided."}
認証情報が指定されてないと怒られてしまいました。では JWT トークンをリクエストに乗せて再度トライ。
$ curl http://localhost:8888/ping -H "Authorization: JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InJhY2NoYWkiLCJ1c2VyX2lkIjoxLCJlbWFpbCI6Imp3dEByYWNjaGFpLmNvbSIsImV4cCI6MTQ2MTY1MzY0N30.UBZrYz79xeI25-Uufmh2zdwZXXzHjamh9rHeOS2Fuqk" {"username":"racchai"}
無事認証が通ってログインユーザーの情報を取得できていますね!
まとめ
django-rest-framework-jwt を使うことで、一瞬でトークンベースの認証を実現することができました。携帯アプリと連携する際には重宝する機能だと思いますので、ぜひご活用ください。
- 作者: 株式会社ビープラウド
- 出版社/メーカー: 秀和システム
- 発売日: 2015/05/21
- メディア: Kindle版
- この商品を含むブログを見る