amplify-swiftを使ってAmazon CognitoでFederated Loginするときにクライアント設定で不必要なIdentity Providerを有効にしない
ていうか有効にしていたつもりもなかったんだけどamplify-swiftがそう動いてしまう、そしてエラーになる、という話。
結論としては、iOSアプリ側にあるamplifyconfiguration.json
において不必要なキーCredentialsProvider
が存在すると自動的に使われてしまいエラーになるので、キーそのものを削除しなければならない。
経緯
Amazon Cognitoを、Google/Facebookその他IDプロバイダーのOAuth認証を通すために使っているが、IdentityProviderとしては使っていない。Web(React)で作っている画面の方ではJS用のAmplifyライブラリを経由していてログインができるんだけど、iOSアプリでSwiftからログイン用の機能を呼び出すと、なんかうまくいかない。認証用の画面が出てきてIDプロバイダー(Google)での認証が通ったあとに画面が閉じて成功も失敗も処理が走らない、という状況になってしまう。
該当のコードはこんな感じなんだけど、signInWithWebUI
が呼ばれたあとのsignInResult
が返ってこず、また例外も出てない。:
@IBAction func tapSignInButton() { Task { do { print("Signing in...") let signInResult = try await Amplify.Auth.signInWithWebUI(for: .google, presentationAnchor: self.view.window!, options: .preferPrivateSession()) print("SignInResult: \(signInResult)") if signInResult.isSignedIn { // let attributes = try await Amplify.Auth.fetchUserAttributes() // print("Sign in succeeded, attributes:\(attributes)") print("Sign in succeeded") } print("Quitting the sign in flow...") } catch let error as AuthError { print("Sign in failed \(error)") } catch { print("Unexpected error: \(error)") } } }
なお設定ファイルamplifyconfiguration.json
は、チュートリアルに従えば作成されるはずなんだけど従っていない*1ので、あれこれ調べて自分で以下のように設定していた。
{ "auth": { "plugins": { "awsCognitoAuthPlugin": { "IdentityManager": { "Default": {} }, "CredentialsProvider": { "CognitoIdentity": { "Default": { "PoolId": "[IDENTITY_POOL_IS_NOT_USED]", // これはこの通りに書いてある "Region": "ap-northeast-1" } } }, "CognitoUserPool": { "Default": { "PoolId": "ap-northeast-1_mypool_id", "AppClientId": "my--app--client--id", "Region": "ap-northeast-1" } }, "Auth": { "Default": { "authenticationFlowType": "USER_SRP_AUTH", "OAuth": { "WebDomain": "my-cognito-domain.auth.ap-northeast-1.amazoncognito.com", "AppClientId": "my--app--client--id", "SignInRedirectURI": "myapplicationname://", "SignOutRedirectURI": "myapplicationname://", "Scopes": [ "email", "openid" ] } } } } } } }
なお最初はWebDomain
にhttps://my-cognito-domain...
のように設定していたところ、signInWithWebUI
が呼ばれたところで「アプリケーションが(null)を開こうとしています」みたいなメッセージが出て白いページが出てきて認証が進まなくなるというウケる状態になってた。そのくらいバリデーションしてほしい……。。。https://
を削除したら先に進み、認証が完了するはずなのにうまくいかなくなるという状態になった。
ログを取る
いろいろ調べてる途中、こんなコードを入れているコード例を見掛けた。
Amplify.Logging.logLevel = .verbose
ので、自分のアプリのコード内でもAmplifyの設定してるところで入れてみた。
do { try Amplify.add(plugin: AWSCognitoAuthPlugin()) try Amplify.configure() Amplify.Logging.logLevel = .verbose print("Amplify configured with auth plugin") } catch { print("Failed to initialize Amplify with \(error)") }
すると次のようなエラーが出ているのがデバッグコンソールに見えた。
1 validation error detected: Value '[IDENTITY_POOL_IS_NOT_USED]' at 'identityPoolId' failed to satisfy constraint: Member must satisfy regular expression pattern: [\\w-]+:[0-9a-f-]+
CredentialsProviderを削除
設定ファイルから以下の部分を削除。
"IdentityManager": { "Default": {} }, - "CredentialsProvider": { - "CognitoIdentity": { - "Default": { - "PoolId": "[IDENTITY_POOL_IS_NOT_USED]", - "Region": "ap-northeast-1" - } - } - }, "CognitoUserPool": { "Default": {
これでうまく動くようになった。やれやれ。