こんにちは、ロジカル・アーツの福島です。
今回はiOSアプリの中でよく見られるユーザーログイン機能の実装を、AWSのサービスであるAmazon CognitoとAWS Amplifyを用いて行いたいと思います。
はじめに
今回はAmplify公式ドキュメントを参考に解説していきます。以下の前提条件の下で手順を進めていきますが、バージョンにより実装が異なる可能性がありますので、詳しくは公式ドキュメントを参照してください。
前提条件
今回の実装は以下のような環境で行います。
項目 | バージョン |
---|---|
OS | macOS BigSur 11.4 |
Xcode | 12.5.1 |
Swift | 5.4.2 |
Node.js | 14.17.0 |
npm | 7.17.0 |
git | 2.32.0 |
AWS CLI | 2.2.8 |
CocoaPods | 1.10.1 |
Amplify | 5.1.0 |
手順
環境構築
まずは前提条件にあるツール群のインストールから行います。
Xcode・Swift
XcodeはApp Storeからインストールすることが可能です。(インストールはこちら)
インストール後、ツールバーから「Xcode→About Xcode」を選択して、version 11.4
以降であることを確認してください。
また、Swiftは標準でインストールされているかと思いますので、バージョンを確認したい場合は以下のコマンドをターミナルで実行してください。
$ swift --version Apple Swift version 5.4.2 (swiftlang-1205.0.28.2 clang-1205.0.19.57) Target: arm64-apple-darwin20.6.0
Node.js・npm
Amplifyはnpmまたはcurlを用いてインストールすることができます。npmでインストールしたい方はまずNode.jsおよびnpmをインストールする必要があります。
これらは公式HPからインストーラをダウンロードすることで簡単にインストールできます。
インストール後に以下のコマンドを実行して、正常にインストールできているかを確認して下さい。
$ node -v v14.17.0
$ npm -v 7.17.0
git
macではgitが標準でインストールされているので、以下のコマンドを実行してバージョンがv2.14.1
以上かを確認してください。
$ git --version git version 2.32.0
AWS CLI
ターミナル上でawsリソースの操作などが可能になるAWS CLIバージョン2をインストールします。
インストーラの手順に従ってインストールが完了したら、以下のコマンドを実行して正常にインストールできているかを確認してください。
$ which aws /usr/local/bin/aws
CocoaPods
Swiftのライブラリ管理を行うCocoaPodsをインストールします。
Macにはデフォルトでgem
コマンドがインストールされているので、以下のコマンドを実行します。
$ sudo gem install cocoapods
インストールに成功したら、CocoaPodsをセットアップするために以下のコマンドを実行します。
$ pod setup
Setup completed
と表示されたらCocoaPodsのセットアップは完了です。
Amplify CLI
Amplify CLI をnpm
かcurl
のどちらかでインストールします。
npmを用いたインストール
$ npm install -g @aws-amplify/cli
curlを用いたインストール
$ curl -sL https://aws-amplify.github.io/amplify-cli/install | bash && $SHELL
次に、Amplify CLIの設定を行います。
$ amplify configure
上記を実行するとブラウザが立ち上がり、マネジメントコンソールのサインインを求められ、新しいIAMユーザーを作成できます。既にIAMユーザーがある場合や、AWS CLIの設定を既に行っている場合はそちらの設定を引き継げるので、この手順は不要です。
※既にお持ちのIAMユーザーを使用される場合は、正しいIAMポリシーが適用されているかを確認してください。
セットアップ
アプリケーションでAmplifyを使用できるようにするためのセットアップを行います。
アプリケーションの作成
今回ログイン機能を実装するアプリケーションを作成します。
まずXcodeを開き、Create a new Xcode project
を選択します。
iOSのAppを選択し、以下のような設定で作成します。
公式ドキュメントではSwiftUIで作成をしていますが、本記事ではStoryboardで作成します。
Amplifyライブラリのインストール
今回はCocoaPodsを用いてライブラリをインストールします。
アプリケーションがあるディレクトリに移動して、pod init
を実行します。
$ cd ~/path/to/MyAmplifyApp $ pod init
現在のディレクトリにPodfile
が作成されますので、Podfile
をvimやテキストエディタで開き、使用するライブラリを入力します。
target 'MyAmplifyApp' do use_frameworks! pod 'Amplify' pod 'AmplifyPlugins/AWSCognitoAuthPlugin' end
Podfile
を保存したら、以下のコマンドを実行してください。
$ pod install --repo-upadte # M1チップ搭載のmacをお使いの場合、上記のコマンドではpodを使用できない場合があります。その場合以下のコマンドを使用してください。 # arch -x86_64 pod install --repo-update
インストールに成功したら現在のディレクトリにMyAmplifyApp.xcworkspace
が作成されますので、そちらのプロジェクトを開いてください。
バックエンド設定
続いて、Amplify CLIを用いてプロジェクトでAWSリソースを使用できるようにします。
アプリケーションがあるディレクトリまで移動しamplify init
を行い、設定を行っていきます。
$ cd ~/path/to/App/MyAmplifyApp $ amplify init ? Enter a name for the project MyAmplifyApp ? Enter a name for the environment dev ? Choose your default editor: Visual Studio Code ? Choose the type of app that you're building ios ? Do you want to use an AWS profile? Yes ? Please choose the profile you want to use default
amplify init
に成功したら、現在のディレクトリに2つのJSONファイル(amplifyconfiguration.json
とawsconfiguration.json
)が作成されます。
この2つのJSONファイルをXcodeのプロジェクト直下にドラッグ&ドロップで追加してください。
- Copy items if needed
- Create groups
- MyAmplifyApp
にチェックが入っていることを確認し、確定してください。
次に、Authカテゴリを追加するため、以下の2つのコマンドを実行します。
$ amplify add auth ? Do you want to use the default authentication and security configuration? `Default configuration` ? How do you want users to be able to sign in? `Username` ? Do you want to configure advanced settings? `No, I am done.`
$ amplify push
これで新しいCognitoユーザープールが作成され、紐づけられました。ユーザープールの詳細については、マネジメントコンソール上で確認することができます。
また、既に作成しているユーザープールを紐付けたい場合、以下のコマンドを実行してください。
$ amplify import auth
アプリケーション設定
次に、アプリケーション側でAmplifyを使うための設定を行います。
AppDelegate.swift
を開き、Amplifyをインポートし、didFinishLaunchingWithOptions
に以下のコードを入力してください。
// AppDelegate.swift import Amplify import AmplifyPlugins ・・・中略・・・ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { do { try Amplify.add(plugin: AWSCognitoAuthPlugin()) try Amplify.configure() print("Amplify configured with auth plugin") } catch { print("Failed to initialize Amplify with \(error)") } return true }
これでセットアップは完了です。
ユーザーの登録
アプリでサインアップを実装することもできますが、今回はCLIでユーザーの登録を行ってみたいと思います。
まず、今回作成したCognitoユーザープールIDを調べます。
$ aws cognito-idp list-user-pools --max-results 20 { "UserPools": [ { "Id": "ap-northeast-1_XXXXXXXXXX", "Name": "myamplifyappXXXXX_userpool_XXXXXX-dev", "LambdaConfig": {}, "LastModifiedDate": "XXXXXXXXXX", "CreationDate": "XXXXXXXXXX" } ] }
表示されたユーザープールIDを使用して、以下のコマンドを実行します。
$ aws cognito-idp admin-create-user \ --user-pool-id ap-northeast-1_XXXXXXXXXX \ --username tarotanaka \ --user-attributes Name=email,Value="foobar@example.com" Name=email_verified,Value=true
これでtarotanakaというユーザーが作成されました。
ただし、この作成方法の場合、ユーザーのステータスがFORCE_CHANGE_PASSWORD
となっており、ログインできません。
以下のコマンドでパスワードを再設定します。
$ aws cognito-idp admin-set-user-password \ --user-pool-id ap-northeast-1_XXXXXXXXXX \ --username tarotanaka \ --password 'L0gicaL4rts' \ --permanent
これでユーザーのステータスがCONFIRMED
となり、ログインできるようになりました。
ログイン
ユーザー名とパスワードでログインするViewを作成します。
// ViewController.swift import Amplify class ViewController: UIViewController { // 各々のオブジェクトとコードを紐付け @IBOutlet weak var usernameTextField: UITextField! @IBOutlet weak var passwordTextField: UITextField! @IBOutlet weak var messageLabel: UILabel! // 画面がロードされた際の初期化 override func viewDidLoad() { super.viewDidLoad() messageLabel.text = "ログインしてください" } // LOGINボタン押下時の挙動 @IBAction func logIn(_ sender: Any) { let username = usernameTextField.text! let password = passwordTextField.text! signIn(username: username, password: password) } // ユーザーログイン機能 func signIn(username: String, password: String) { Amplify.Auth.signIn(username: username, password: password) { result in switch result { case .success: self.changeMessage(message: "ログイン成功!") print("Sign in succeeded") case .failure(let error): self.changeMessage(message: "ログイン失敗…") print("Sign in failed \(error)") } } } // messageLabelのテキストを変更 func changeMessage(message: String) { DispatchQueue.main.async { self.messageLabel.text = message } } }
AmplifyライブラリのAuth.signIn
メソッドを使用することで簡単にログインすることが可能です。
ログアウト
ログアウトボタンを追加します。以下のコードをViewController.swift
のViewControllerクラスに追記してください。
// LOGOUTボタン押下時の挙動 @IBAction func logOut(_ sender: Any) { signOut() } // ログアウト機能 func signOut() { Amplify.Auth.signOut(options: .init(globalSignOut: true)) { result in switch result { case .success: self.changeMessage(message: "ログアウトしました") resetTextField() print("Successfully signed out") case .failure(let error): self.changeMessage(message: "ログアウトに失敗しました") print("Sign out failed with error \(error)") } } } // テキストフィールドの初期化 func resetTextField() { DispatchQueue.main.async { self.usernameTextField.text = "" self.passwordTextField.text = "" } }
起動時にログイン状態を確認する
現在アプリでは、起動時にmessageLabel
を「ログインしてください」という文字列に初期化するように記述しています。
・・・ override func viewDidLoad() { super.viewDidLoad() messageLabel.text = "ログインしてください" } ・・・
これではログインしたままアプリを再起動させた場合、ログインしているにも関わらず「ログインしてください」と表示されてしまいます。
これを改善するために、起動時にログイン状態を確認するようにしてみましょう。
・・・ override func viewDidLoad() { super.viewDidLoad() // 現在同端末でログインしているユーザーがいるかの確認 if Amplify.Auth.getCurrentUser() != nil { messageLabel.text = "ログインしています" } else { messageLabel.text = "ログインしてください" } } ・・・
これで起動時にログイン状態を確認し、messageLabel
に表示することができます。
起動時にログインしている場合、messageLabel
は「ログインしています」となります。
これでログインとログアウトの機能を実装することが出来ました。
まとめ
今回はAmazon CognitoとAWS Amplifyを用いてiOSアプリのログイン機能を実装しました。
環境構築としてCLIツールのダウンロードはありますが、実装自体は非常に簡単に出来ることが分かります。
また、今回はCLIを使用してデフォルト設定のCognitoユーザープールを作成しましたが、マネジメントツールからカスタマイズしたユーザープールを作成してそれをアタッチすることもできます。
ログイン機能以外にも、非常に便利なライブラリやメソッドが揃っているので是非使用してみてください。