Vueアプリでトークン認証のログインシステムを作る

準備するもの

・Django RESTとToken Authができている環境

・Vueのアプリ

アプリ紹介

今回は、フロントエンドがVueでバックエンドがDjangoでできているチケット管理システムのログインのシステムを作成します。

例として、従業員がお客様からの問い合わせに対してチケットを作成していくようなイメージです。

Vueがフロントエンド(クライアント側)でDjangoのAPIのエンドポイントからデータを発信しています。

しかし、このAPIが公共に垂れ流しの状態なのでURI(URL)にアクセスできる人誰でもこのデータにアクセスできてしまいます。

前回はDjango RESTFramewrokを使ってトークンAuthでこのトークンがある人だけデータにアクセスできる人だけAPIのリクエストにデータをリスポンスとして返すことができました。

今日はそれをVueのアプリから行っていきたいと思います。

アプリの準備

DjangoアプリはこちらのURLのGitHubからクローンしてください。

https://github.com/TraitOtaku/djangoAPI/tree/8_AuthReady

Vueのアプリはこちらからダウンロードしてください。

https://github.com/TraitOtaku/VueApp/tree/4_AuthReady

Gitのコマンドを使ったことがない人は面倒でも必須のスキルですので必ず覚えておくようにしましょう。

Gitのコマンドです。

git clone URL

cd /to/repo/

git branch -a

Git checkout <branch_name> 

Djangoの準備の仕方は他の動画でも説明しているので今回は飛ばします。

Vueもnpmかyarnでライブラリをインストールして準備完了です。

npm i

EventService.js

まずは、ログインする際にDjangoにユーザー名とパスワードをJSONファイルで送りつけます。この際POSTリクエストになっていることに注意しましょう。

で、正しいクレデンシャル(ログイン情報)が遅れた後にDjangoからTokenが返されます。

const loginClient = axios.create({

  baseURL: "http://127.0.0.1:8000/",

  withCredentials: false,

  headers: {

    Accept: "application/json",

    "Content-Type": "application/json",

  },

});
  submitLogin(logininfo) {

    return loginClient.post("api-token-auth/", logininfo);

  },

ちなみにapiClientというファンクションでDjangoのTokenAuthに必要なTokenをリクエストの際に送るヘッダーに付けてあげるようにしています。

const apiClient = axios.create({

  baseURL: "http://127.0.0.1:8000/api",

  headers: {

    Authorization: `Token ${localStorage.getItem('token')}`,

    "Content-Type": "application/json",

  },

});

では、このJavaScriptをエキスポートして、LoginView.vueのコンポーネントを作成します。

LoginView.vue

このページ(コンポーネント)でログインに関連するシステムを構築しています。

AntDesignのUIライブラリからコピペしたフォームと、そのサブミットボタンにクリックイベントを付けてます。

    const submitLogin = () => {

      EventService.submitLogin(toRaw(formState))

        .then((response) => {

          console.log(response.data);

          localStorage.setItem('token', response.data.token)

          router.push({ name: 'home' })



        })

        .catch((error) => {

          console.log("Error" + error);



        });

    }

で、ここで、Django から返ってきたトークンをブラウザのストレージにtokenというキーで保管しておきます。

これでログインができたらrouter.pushでホーム画面にジャンプするように設定しています。

本来なら、ログインしない限りhomeのページへのアクセスはできないようにするのがベストですが、今回は割愛しています。

もしするのであればv-ifとvuexでState managementを使うのがベストだと思います。

また、ログインのエラーがあった場合のロジックもここに追加できますね、。

では、ログインができたらHomeViewに行くのでそこにログアウトのボタンも作成しましょう。

HomeViews.vue

ログアウトのロジックは下記のようなコードでできます。

単純にlocalStorageに保管されているtokenアイテムを取り除き、router.pushのコマンドでログイン画面に誘導してあげます。

    const logOut = () => {

      localStorage.removeItem('token')

      router.push({ name: 'login' })

    }

まとめ

まあ、全体的に煩雑なコードですが、これでVueアプリからDjangoのToken AuthのAPIにアクセスすることができました。

バックエンドのテクノロジーとAuth(認証)のやり方によって、ヘッダーの書き方が変わることに注意しましょう。

あとはサインアップと、パスワードを忘れた際の再設定のロジックもDjango側と一緒に作成していけばプロダクションで使えそうですね。

お疲れ様です。

Django API Authってなに?Token Authenticationを使ってみよう

サマリー

APIのエンドポイントを守れ!
 

準備するもの

  • Pythonとpip
  • Django RESTFrameworkのプロジェクト

Authってなに?

Authは認証のことで、Autheniticationの事を意味します。ここで、Authorizationと間違える事が多いですがこの2つは全くの別ものなのでちゃんと理解をしておきましょう。

Authentication(認証)→誰かを証明すること

Authorization(権限を与える)→特定のデータへのアクセスを許可するか

なのでAuth(認証)された人がどのPermissionがあるのかを判断する方法になり、それから、認証された人が特定のデータにアクセスできるかをAuthorizeするわけですね。

例でいうと会社のセキュリティカードを持っていればそのカードのステータスによってアクセスできる場所が決まってくるような感じでしょうか。

Authはなぜ必要か

APIのエンドポイントのURI(URL)にアクセスできる誰もがその情報を手に入れることができます。その情報を守るために認証された人だけにデータのアクセス権限を与えるためです。

特にデータの更新や削除ができる権限は限られた人だけに与えたいですよね。

Authの種類について

Djangoで主流なAuthシステムを紹介します。

  1. Basic Authentication→ログインIDとPWだけの簡単なものです。
  2. Token Authentication→トークンを使ってHTTP認証をします。クライアント・サーバーセットアップのデスクトップアプリやモバイルアプリに最適です。
  3. SessionAuthentication→DjangoについてくるセッションAuthのシステムを使えます。時間が経つとログアウトされる仕組みとかも作れます。
  4. JWT(JSON Web Toekn)→ ここ数年で人気になったJSONウェブトークンでの認証システムです。

BasicAuthenticationを使おう

他にJWTとDjoserのライブラリもお勧めです。

まずは公式ドキュメンテーションを読みましょう。

https://www.django-rest-framework.org/api-guide/authentication/

settings.pyの設定

ではプロジェクトディレクトリ内のsettings.pyに下記のラインを追加しましょう。

REST_FRAMEWORK = {

    'DEFAULT_AUTHENTICATION_CLASSES': [

        'rest_framework.authentication.BasicAuthentication',

        'rest_framework.authentication.SessionAuthentication',

    ]

}

Views.pyの設定

ここでAiuthenticationに必要なモジュールをインポートします。

from rest_framework.authentication import SessionAuthentication, BasicAuthentication

from rest_framework.permissions import IsAuthenticated

あとは、クラスを貼り付けるだけ!

from .models import Member

from .serializers import MemberSerializer

from rest_framework import viewsets

#これを追加

from rest_framework.authentication import SessionAuthentication, BasicAuthentication

#これを追加

from rest_framework.permissions import IsAuthenticated




class MemberViewSet(viewsets.ReadOnlyModelViewSet):

    #これを追加

    authentication_classes = [SessionAuthentication, BasicAuthentication]

    #これを追加

    permission_classes = [IsAuthenticated]



    queryset = Member.objects.filter(status="Employed")

    # queryset = Member.objects.all()

    serializer_class = MemberSerializer

APIのエンドポイントの確認

では、DjangoのユーザーでログインしていないブラウザでURIにアクセスしましょう。

このように、APIのデータが出力されなくなりましたね。

ここで重要なのが、APIの発信元がHTTPSでないとログイン情報が盗まれることがあるので必ずHttps://を使うようにしましょう。

しかし、これだとDjangoのアドミンパネルからログインしていないとAPIが見れないのでクライアント側では使えなさそうですね。

(※このログインページはカスタマイズできますが次の方法で試してみましょう。)

TokenAuthを使おう

ではAuthのイメージが沸いたところでTokenAuthの設定をしていきます。

settings.pyの設定

では、REST_FRAMEWORKの項目を下記のように更新しましょう。

REST_FRAMEWORK = {

    'DEFAULT_AUTHENTICATION_CLASSES': [

        'rest_framework.authentication.TokenAuthentication'

    ],

    'DEFAULT_PERMISSION_CLASSES': [

        'rest_framework.permissions.IsAuthenticated'

    ]

}

では、Views.pyのAuthも項目は一旦削除しましょう。

で、APIのエンドポイントに行くとデータが見れなくなったことがわかりましたね。

http://127.0.0.1:8000/api/?format=api

このAPIのルートから全てTokenがないとアクセスが制限されます。

ちなみにこれをなくして、viewごとでauth設定をすることもでき、一部のapiだけにauthをかけられます。

Tokenを取得するURLを作成

まずはsettings.pyに下記のtokenアプリを追加します。

INSTALLED_APPS = [

    ...

    'rest_framework.authtoken'

]

ではurls.pyにTokenを作成するURLを作成します。

from rest_framework.authtoken import views




urlpatterns = [

    path('api-token-auth/', views.obtain_auth_token, name='api-token-auth')

]

URLの名前はなんでもよいです。

アプリを登録した後にDBのマイグレーションを忘れないようにしてください。

これでToeknテーブルがアドミンパネルに表示されました。

これでユーザーがログインしたときに生成されるトークンと照らし合わせてアクセス権限を判断できるようになります。

ログイン情報を作成

もし、ログインする情報がない人は先にスーパーユーザーを作っておきましょう。

python manage.py createsuperuser

テストでリクエストを送ってみる

では下記のURLにアクセスしてみます。

http://127.0.0.1:8000/api-token-auth/

下記のようにGETリクエストが拒否されました。

ではログイン情報と一緒にPOSTメソッドでリクエストを送ってみます。

HttpieでURLにPOSTリクエストを送る

では下記のコマンドでテストツールのhttpieをインストールします。

pip instal httpie

で、先ほど作成したapi-token-authのURLにPOSTリクエストを送ります。

http POST http://127.0.0.1:8000/api-token-auth/ username="admin" password="admin"

これでTokenが作成されればOKです。

トークンを使ってAPIにアクセスする

では先ほど作成されたTokenを使ってAPIにアクセスできるか試してみましょう。

http http://127.0.0.1:8000/api/tickets/ “Authorization: Token 330b6d34c6ac24a3606b14495e9311e0681821c2”

問題なくレスポンスがかえってきましたね。

※同じようにHTTPSを使うようにしましょう。