axiosの使い方 - headerの付与とか色々
以下のページからREST APIを叩く上でのベストプラクティス(と勝手に思っているもの)を抽出します。
- リクエストを投げるたびにheaderなどを設定する例
- 先に付与する情報を設定しておく例(default config上書き)
- 先に付与する情報を設定しておく例(axiosのインスタンスを分ける)
- おまけ
リクエストを投げるたびにheaderなどを設定する例
GET
先日のエントリ(↑)で使用したコードのaxios部を取り出すと下記な感じです。
import axios from 'axios'; const API_BASEURL = "http://127.0.0.1:8000/api/" axios.get(API_BASEURL + "books/") .then((response) => { console.log(response); }) .catch((error) => { console.log(error); }) .finally(() => { })
このコードを実行したときのGETパケットは以下のようになります。(画像はクリックで拡大します。見比べる場合には別のウィンドウで開くと見やすいです)
特に設定していないため、もちろん「Authorization」ヘッダが付与されていないのがわかります。(わからなければ次のコード例の実行時スクショと比べてください。)
今回はここにJWTトークンを使った認証(Django REST framework JWT)を組み込みます。
まずはaxios.get()の引数に毎回 {headers: ...}
を入れる方針。
import axios from 'axios'; const API_BASEURL = "http://127.0.0.1:8000/api/" const API_TOKEN = "TOKENVALUEEXAMPLE" axios.get(API_BASEURL + "books/", { headers: { Authorization: "JWT " + API_TOKEN } }) .then((response) => { console.log(response); }) .catch((error) => { console.log(error); }) .finally(() => { })
このコードを実行したときのGETパケットは以下のようになります。 ちゃんとAuthorizationヘッダが付与されているのがわかります。
POST
まず最初に、tokenを付与しない例。
import axios from 'axios'; const API_BASEURL = "http://127.0.0.1:8000/api/" const API_TOKEN = "TOKENVALUEEXAMPLE" axios.post(API_BASEURL + "users/", {employee_id: "123456"}) .then((response) => { console.log(response); }) .catch((error) => { console.log(error); }) .finally(() => { })
生パケットは以下。データがちゃんと入っているが、もちろん「Authorization」ヘッダは入っていない。
次に、GETのときと同じようにtokenを付与する例。
import axios from 'axios'; const API_BASEURL = "http://127.0.0.1:8000/api/" const API_TOKEN = "TOKENVALUEEXAMPLE" axios.post(API_BASEURL + "users/", { employee_id: "123456" }, { headers: { Authorization: "JWT " + API_TOKEN } }) .then((response) => { console.log(response); }) .catch((error) => { console.log(error); }) .finally(() => { })
付与した結果は以下のようになります。
ちなみに
間違えて以下のように書くと、
axios.post(API_BASEURL + "users/", { employee_id: "123456", Authorization: "JWT " + API_TOKEN }) .then((response) => { console.log(response); }) .catch((error) => { console.log(error); }) .finally(() => { })
パケットは次のようになります。
HTTP Request Headerではなく、Request Bodyのjsonに「Authorization」要素が入ってしまっています。理解できるとそりゃそうやなって感じだと思います。
先に付与する情報を設定しておく例(default config上書き)
GET
import axios from 'axios'; const API_BASEURL = "http://127.0.0.1:8000/api/" const API_TOKEN = "TOKENVALUEEXAMPLE" axios.defaults.baseURL = API_BASEURL; axios.defaults.headers.common["Authorization"] = `JWT ${API_TOKEN}`; axios.post(API_BASEURL + "users/", { employee_id: "123456" }) .then((response) => { console.log(response); }) .catch((error) => { console.log(error); }) .finally(() => { })
POST
import axios from 'axios'; const API_BASEURL = "http://127.0.0.1:8000/api/" const API_TOKEN = "TOKENVALUEEXAMPLE" axios.defaults.baseURL = API_BASEURL; axios.defaults.headers.common["Authorization"] = `JWT ${API_TOKEN}`; axios.post(API_BASEURL + "users/", { employee_id: "123456" }) .then((response) => { console.log(response); }) .catch((error) => { console.log(error); }) .finally(() => { })
先に付与する情報を設定しておく例(axiosのインスタンスを分ける)
この方法はAPIの種類ごとにヘッダを付与するかどうか分ける必要があるときに便利そうです。(ex: トークン発行関連のAPIを呼ぶときだけはAuthorizationヘッダを付けないようにしたい、など)
同じなのでPOSTのコード例だけ下記に示します。
import axios from 'axios'; const API_BASEURL = "http://127.0.0.1:8000/api/" const API_TOKEN = "TOKENVALUEEXAMPLE" const generalApiInterface = axios.create({ baseURL: API_BASEURL, headers: { "Authorization": `JWT ${API_TOKEN}` } }) generalApiInterface.post(API_BASEURL + "users/", { employee_id: "123456" }) .then((response) => { console.log(response); }) .catch((error) => { console.log(error); }) .finally(() => { })
Reactで実装する際には実際にはこの方法を使用し、generalApiInterfaceをReduxのStoreに突っ込んでおくのが良いと思います。 (トークンの有効期限が切れたときにこのgeneralApiInterfaceを書き換えたいため)
(ソフトウェア開発はこの「この方法を使用したらいい」の判断が難しいです。この判断ができれば実装できたも同然です。)
おまけ
Web系システムのデバッグにはWiresharkがおすすめです。
使いこなすのは難しいかもしれませんが、低レイヤのパケットを生で見られるようになっておくとハマった時に助かります。知識の補強にもなりますので是非。
ブラウザとサーバさん、最近のWeb系技術だと色々おしゃべりしてて見てて楽しいです。