【SwiftUI】とDjango-REST-Framework(Django-AllAuth)でログイン・ログアウト機能の実装

この記事では、SwiftUIとDjango-REST-Framework(Django-AllAuth)でログイン・ログアウト機能の実装方法を紹介します。

 

◆動作検証環境

・ローカル環境:mac Catalina
・XCode:12.1
・Django:3.1.2
・django-allauth:0.43.0
・DjangoRESTframework: 3.12.1
・django-rest-auth: 0.9.5
今回の記事ではバックエンドにDjangoRESTframeworkのプロジェクトを利用しています。

 

本記事で利用しているものと同じプロジェクトの設定方法等は、下記の記事で紹介しています。

 

前回までの記事で紹介している、ユーザー登録実装後のコードを利用して解説しています。
ユーザー登録の実装方法は下記の記事で紹介しています。

 

なお、SwiftUIの基本的な文法等については、解説していません。
スポンサードリンク

ログイン画面の構成と動作内容

 

まずは、iOSアプリのログイン画面を作成します。

ログイン画面の構成内容は以下のとおりです。

  • email入力欄
  • パスワード入力欄
  • ログインボタン
  • ログアウトボタン
  • パスワード再設定用リンク

ログイン画面の構成内容は以下のとおりです。

 

通常のログイン画面には、ログアウト用のボタンはありませんが、今回は動作の確認用として同じ画面設置して機能を確認します。

 

パスワード再設定用リンクは、django-rest-framworkのエンドポイントを使って再設定する方法ではなく、django-allauthで設定しているパスワード再設定ページ(WEBサイト)を表示するようにしています。

 

django-rest-framworkのエンドポイントを使って再設定する方法は、入力したメールに設定用のリンクが貼られそちらから、再設定用の画面に遷移する仕組みです。

 

シングルページのWEBサイトの場合、この遷移先にエンドポイントを使う再設定ページを作成できますが、モバイルアプリの場合はメール画面から、再度アプリの画面へ遷移する事ができないため、この方法としています。

 

動きとしては、email、パスワードを入力し登録ボタンをタップ。

  • 入力が正しければ、ログイン成功とコンソールに表示
    通常はログイン成功後の画面に遷移させます
  • 入力が正しくなければ、alertを出し不備に内容を知らせる。

 

ログアウトボタンをタップした際は、ログアウト用のエンドポイントにアクセスし、ログアウトします。
今回はログアウトのメッセージをコンソールに表示します。

入力のバリデーションは、django-rest-framwork側で行い、エラーがある場合は、responseのメッセージをalertで表示させます。

 

ログアウト登録画面のコーディング

 

ログイン用画面のstructは以下の内容です。

NavigationViewに含まれる画面となっており、親の画面はユーザー登録用画面をしています。

 

LoginView

コーディングのポイントは以下のとおりです。

 

45、55行目:

ログイン、ログアウトそれぞれのボタンのタップで、makeLogin() 、makeLogout() を利用します。

 

67行目:

isActivePasswordResetView = true とする事で、WEBビューを利用するパスワードのリセット画面を表示させます。

このビューはStackNavigattionの含まれ、対象のフラグが立つと画面遷移します。

 

74行目:

メールアドレス、パスワード等に入力の不備があった際に、アラートで表示します。

 


AccountAPI.swift

ポイントは以下のとおりです。

 

ログイン処理の構成は、基本的なPOST接続と同様です。

60行目:

dataTask() で受け取ったdataをJSONSerialization.jsonObject( で、JSONデータをパースした際にログイン成功時に発行されるTokenを取得します。

ユーザー登録や、ログイン時の入力情報に不備があった際に受け取るエラーメッセージと同じ方法で、["key"] と指定します。

 

104行目:

バックグラウンド下での@Published 変数の変更を避けるために、DispatchQueue.main.async を使いTokenキーを代入します。

*アプリの再起動時等にもログイン済みの状態を把握するために、UserDefaultなどでデバイスにTokenキーの保持、削除する方法も利用されます。

 

ログアウト処理の構成も、基本的なPOST接続と同様です。

163 行目:

dataTask() で受け取ったdataを確認のためにコンソールに表示します。

ログアウト処理が正常に行われると、ログイン処理時に作成されたTokenが削除されます。

次回以降のログインは、新しいTokenが発行されそちらを利用するようになります。

 

ここでは、単純にログアウトするだけの機能ですが、実際はStatusコード200番だったら、指定のビューへ遷移する等の処理を加えます。

 

rest-authとall-authのログイン方法の違い

 

Django-restauthをモバイルアプリ等で使う場合、共通のデータベースをWEBアプリでも使用する場面は多いと思います。

WEBアプリでall-authでユーザー登録、ログインする場合

モバイルアプリでrest-authでユーザー登録、ログインする場合では少々違いがあるので、まとめてみます。

 

WEBアプリ
All-Auth
モバイルアプリ
Rest-Auth
ユーザー登録登録Tokenは発行されないTokenが発行される
ログイン成功後Tokenは発行されないTokenが発行される
*モバイルアプリでユーザー登録した場合、
同じTokenが発行される
*WEBアプリでユーザー登録した場合、
新規のTokenが発行される
ログアウトモバイルアプリログイン時発行された
tokenは削除されない
Tokenが削除される
(次回のログイン時は新規のTokenが発行される)

 

WEBアプリで登録されたユーザーが、モバイルでログインする → Tokenが発行される

モバイルアプリで登録されたユーザーがWEBアプリでログインする → Tokenは発行されない(パスワード認証)

ひとつのユーザーが、WEB、モバイル同時にログイン → できる

 

モバイルの場合、各エンドポイントの権限はserializerクラスで設定するが、Token認証にする場合は、ログイン時に発行されるTokenを利用する。

 

SwiftUIアプリの実践的なログイン・ログアウト処理の実装

 

ログイン等の認証機能のあるアプリケーションでは、通常一度ログインを行うと、ログアウト処理をするまでは専用のビューが表示される方法がよく利用されます。

例えば、アプリを開いた際に、

  • ログイン済みのユーザーは → 会員用ビューに自動で遷移 → ログアウト処理を行うとログイン画面に遷移
  • ログインしていないユーザーは → ユーザー登録またはログイン画面に遷移

というような動作です。

 

これまでに紹介したコードの内容だと、一度アプリを再起動してしまうと、Tokenの値が消えてしまいますので、そのような環境に対応できる形で対応します。

 

動作の内容は以下のとおりです。

 

  1. アプリを開く際にすでにログイン処理をしており、Tokenを発行している場合はログイン後(HOME画面)に遷移される。
    Tokenが発行されていない場合は、ログイン画面が表示される。
  2. ログイン処理を行い、成功すると発行されたTokenを@Published変数に格納する。
  3. ログアウト処理を行うと、Tokenの値を””とする
  4. ライフライクルがアクティブからバックグラウンドに映る際に、Published変数に格納されたTokenの値をUserDefaultsを利用して、デバイスに保持する
    (ログイン済みの場合→”XXXXXXXXX12345XXXXXX”, ログインしている場合→””となっている)
  5. ライフライクルがバックグラウンドからアクティブに際に、UserDefaultsを利用してデバイスに保持されているTokenの値をPublished変数に格納する
    ①に戻る

 

アクティブ⇔バックグラウンドの際にTokenの値をデバイスから出し入れするため、アプリの再起動にも値を保持した状態となります。

 

上記の動きにするため下記のようなコードに編集します。

 

AccountAPI.swift / ログイン処理の部分

 

ポイントは以下のとおり

28行目:

ログインが成功した時は、@Published変数にのTokenの値を入れる

UserDefaultsを使用する際はここで処理します。

 

29行目:

ログインした後に指定のビューに遷移するように、対象のフラグをtrueにする

 

AccountAPI.swift / ログアウト処理の部分

 

ポイントは以下のとおり

10行目:

ログアウトがされた時は、@Published変数のTokenの値を””とする

UserDefaultsを使用する際はここで処理します。

 

11行目:

ログアウトした後にログインビューに遷移するように、対象のフラグをtrueにする

 


 

以上、SwiftUIとDjango-REST-Framework(Django-AllAuth)でのログイン・ログアウト機能の実装方法を紹介しました。