django_restframeworkでjwtトークン認証を実装したAPIをvueからaxiosで叩く

# 目的
django_restframeworkで実装したAPIをvueからaxiosで叩くことはしたが、実務のようにJWTを利用したトークン認証を行う

# 実施環境
### ハードウェア環境
| 項目 | 情報 |
|:-:|:-:|
| OS  |macOS Catalina(10.15.7)   |
|ハードウェア   |  MacBook Air (11-inch, Early 2015) |
|プロセッサ   | 1.6 GHz デュアルコアIntel Core i5|
|メモリ   |  4 GB 1600 MHz DDR3 |
|グラフィックス   |  intel HD Graphics 6000 1536 MB |
### ソフトウェア環境
| 項目 | 情報 |
|:-:|:-:|
| homebrew  | 3.3.8 |
| mysql | Ver 8.0.27 for macos10.15 on x86_64 |
| @vue/cli | 4.5.15 |
| vue | 2.6.14  |




# 前提
今回の記事はこれまでの[【django/vue.js初学者向け】DjangoRestFrameworkで作成したAPIをVue.jsから叩いてみる](https://qiita.com/yutoun/items/4db555c3031860e4880a)と[【簡単】django_restframeworkのjwt認証を最低限実装していく](https://qiita.com/yutoun/items/f750d82d811a85b9304b)の続きのため、これらの記事を読まないとわからない可能性がある。


# 概要

JWT認証のトークンを取得するAPIとJWTのアクセストークンがなければAPIを叩けないと言う処理の実装、APIを叩くためのフロント画面の実装が上記で完了しているため、これらを組み合わせていく。

# 詳細
①v-modelで入力されたusernameとpasswordをscriptのプロパティに格納

```vuejs
{
 username: '',
 password: '',
}

```
②ログインボタンを押すと@click(v-on:click)でloginメソッドが実行され、プロパティのusernameとpasswordを利用して[【簡単】django_restframeworkのjwt認証を最低限実装していく](https://qiita.com/yutoun/items/f750d82d811a85b9304b)で実装したAPIを「http://127.0.0.1:8000/api-auth/jwt/」 のエンドポイントから叩く。

```vuejs
login: function(){
      // token取得のためのusernameとpasswordセット
      const data = {username: this.username, password: this.password}
      // access_token&refresh_tokenを取得
      this.axios
        .post("http://127.0.0.1:8000/api-auth/jwt/",data)
        // レスポンスを一旦tokensプロパティに格納
        .then(response => (this.tokens = response.data));
    }
```

③レスポンスのアクセストークンとリフレッシュトークンをそれぞれプロパティに格納
```.then(response => (this.tokens = response.data));```

```json
tokens: {
          "refresh":'',
          "access":''
       },
```


④メンバー情報取得ボタンを押すと@click(v-on:click)でgetMemberメソッドが実行され、```http://127.0.0.1:8000/api/v1/member/"```に対してgetメソッドで情報を取得する

⑤今回はサーバサイドでAPIにJWT認証が必要となる設定をしているため、Headerに
```{Authorization: アクセストークン}```を含める必要がある。そうしなければ認証されていませんとエラーが出る。

⑥そこで先ほど取得したアクセストークンをheaderに

```{Authorization: アクセストークン}```を含める。

```vuejs
this.axios
      .get("http://127.0.0.1:8000/api/v1/member/",{headers: {
        // postmanでのAPIcal同様にJWTが必要
        // 検証モードで確認できるヘッダー
        "Authorization": 'JWT ' + this.tokens.access,
      }
})
```

⑦Membersプロパティにレスポンスを格納し、それぞれのメンバーの特徴をループ処理で表示する

```vuejs
<div v-for="(member, key) in Members" :key="key">
      <hr>
      <p>{{ member.username }}</p>
      <p>{{ member.gender }}</p>
      <p>{{ member.introduction }}</p>
      <p>{{ member.job }}</p>
      <hr>
    </div>
```

# 大枠

```vuejs
<template>
  <div>
    <!-- Membersプロパティから -->
    <div v-for="(member, key) in Members" :key="key">
      <hr>
      <p>{{ member.username }}</p>
      <p>{{ member.gender }}</p>
      <p>{{ member.introduction }}</p>
      <p>{{ member.job }}</p>
      <hr>
    </div>
    <!-- scriptのuserプロパティに入力値が格納される -->
    <input type="text" placeholder="username" v-model="username">
    <!-- scriptのpasswordプロパティに入力値が格納される -->
    <input type="text" placeholder="password" v-model="password">
    <!-- クリックするとloginメソッドを実行 -->
    <button @click="login">login</button><hr>
    <!-- クリックするとgetInfoメソッドを実行 -->
    <button @click="getInfo">メンバー情報を取得</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      Members: [],
      tokens: {
        "refresh":'',
        "access":''
      },
      username: '',
      password: '',
    };
  },
  methods: {
    // メンバーの各情報を取得
    getInfo: function(){
      this.axios
      .get("http://127.0.0.1:8000/api/v1/member/",{headers: {
        // postmanでのAPIcal同様にJWTが必要
        // この通信がうまくいかない時はchromeの検証モード/networkから確認できる
        "Authorization": 'JWT ' + this.tokens.access,
      }
      })
      // レスポンスをMembersプロパティに格納
      .then(response => (this.Members = response.data));
    },
    // usernameとpasswordからjwt認証を行いaccess_tokenとrefresh_tokenを取得
    login: function(){
      // token取得のためのusernameとpasswordセット
      const data = {username: this.username, password: this.password}
      // access_token&refresh_tokenを取得
      this.axios
        .post("http://127.0.0.1:8000/api-auth/jwt/",data)
        // レスポンスを一旦tokensプロパティに格納
        .then(response => (this.tokens = response.data));
    }
  }
};
</script>
```

Vueの実装はこれで最低限の機能は揃ったのではないだろうか