MawaLog

一日一日、楽しく生きる。技術と音楽が好き。

Django REST framework JWTを使ったwebAPI経由のログイン認証動作確認をPythonで実装する

Django REST framework JWTを使ってwebAPI経由のログイン認証を実装する

Django REST framework JWTのページに解説が書いてある。 getblimp.github.io

上記のマニュアルどおりにセッティングしたあとにログイン認証動作テストをしてみる。まずは、マニュアルにも載っているLinuxCURLコマンドで行う。

CURLコマンドでのアクセス

"""
1:tokenを取得
"""
$curl -X POST -H "Content-Type: application/json" -d '{"username":"*******<username>*******","password":"*******<password>*******"}' http://localhost:8000/<auth url>/
"token":"***********<token>*************"} #レスポンスでトークンが返ってくる
"""
2:APIでログイン認証してAPI作動させる
"""
$curl -H "Authorization: JWT ***********<token>*************" http://127.0.0.1:8000/api/***<api_url>***/
#※クエリ結果が返ってくる

無事クエリが返ってきたのでOK。

Python requestsでのトークン取得

別のpythonプロジェクトからwebAPIを扱う場合、CURLよりrequestsで使えるようにしておくため、CURLのコマンドをpythonで書き替えた場合のコードを検証する。

"""
1:tokenを取得
"""

import requests

headers = {
    'Content-Type': 'application/json',
}

data = '{"username":"*******<username>*******","password":"*******<password>*******"}'

r =requests.post('http://localhost:8000/<auth url>/', headers=headers, data=data)
print("token==>",r.text)
print()

#token==> {"token":"***********<token>*************"} とprintされる
#※注意実は文字列で"{"token":"***********<token>*************"}"となっていることに注意!
#なので以下のjsonモジュールで辞書型に変換した後にtokenを抜き出す

でもこれだと実戦ではうまくいかないことのほうが多いです。下記が実践的内容です(多分)

実践的内容

import json

data={}
data["username"]="*******<username>*******"
data["password"]="*******<password>*******"

r =requests.post('http://localhost:8000/<auth url>/', headers=headers, data=json.dumps(request_data))
print("token==>",r.text)
print()

#username と password がユーザーによって変わる場合は↑のようにjsonデータとして追加データを載せないと失敗しますので注意
"""
2:token文字列から辞書へ変換
"""

import json

dict = json.loads(r.text)
dict["token"]

"""
3:APIでログイン認証してAPI作動させる
"""

headers = {
    'Authorization': 'JWT {}'.format(dict["token"]),
}

#↑JWT以降の半角スペースも注意

contents = requests.get('http://localhost:8000/api/***<api_url>***/', headers=headers)
print("query==>",contents.text)

#※query==> "クエリ結果・・・・"が返ってくる

ローカルで、うまく動作確認ができた。

トークンを永続化するには

社内APIなどでは、毎回トークン発行する必要性も少ないのでトークンは一発でもいいという状況もあるはず。

ちなみにトークンを永続化する場合は、

#Django settings.py内
・
・
・
##jwt
JWT_AUTH = {
    'JWT_VERIFY_EXPIRATION': False,
    'JWT_AUTH_HEADER_PREFIX': 'JWT',
}
・
・
・

と設定ファイルに記載してください。

httpsアドレスの場合はミドルウェア設定が必要!

SSL通信だとこの実装形式だとtoken発行までは行けるけども、tokenとともにAPI経由ログインがうまくいかない・・・ 解決策は↓

stackoverflow.com

apacheの設定ファイル内(自分の場合enable_mod_deflate.conf)

<IfModule mod_headers.c>
・
・
・
</IfModule>
#jwt_auth_enable
WSGIPassAuthorization On #←ここの一行を加える!

これでうまく行きます!httpローカル環境テストで上手く行っても罠がありますのでお気をつけて・・・