KITCHEN DRINKER

主にAndroid開発メモとか

Amazon Cognito で Sign in with Apple 対応

AndroidにてAmazon Cognito で User Pool を使って Sign in with Apple 対応した際に、情報少なくて困ったので誰かの助けになればとメモ。

AmazonAmplifyというLibraryを用意してくれてるのですが、認証機能以外にも色々モリモリ詰まったものなので

本当は少し古いけどよりシンプルなこちらを使いたかったのですが、 Sign In with Apple には対応してない?ようで、大人しくAmplify を使うことにしました。(結果アプリサイズが4M増えました…ツライ)

通常ならこれ通り進めていけば大丈夫です。 docs.amplify.aws

build.gradle

classpath 'com.amplifyframework:amplify-tools-gradle-plugin:1.0.1'

※ 公式には apply plugin: 'com.amplifyframework.amplifytools' も追加するように書いてありますが、追加せずとも動作しました。

app/build.gradle

implementation 'com.amplifyframework:core:1.0.0'
implementation 'com.amplifyframework:aws-auth-cognito:1.0.0'

他、gradleのversionを4.0.0にしました。

必要なファイルは2つ。 本番用と開発用と環境を分けている場合には各環境毎に用意する必要があります。

  • app/src/res/raw/awsconfiguration.json
  • app/src/res/raw/amplifyconfiguration.json

上記のファイルはamplifyコマンドを実行することで自動で作られるのですが、そのためにはAWSへIAMユーザ登録が必要になります。 このために登録したくなかったので、手動で作りました。

awsconfiguration.json

{
  "UserAgent": "aws-amplify/cli",
  "Version": "0.1.0",
  "IdentityManager": {
    "Default": {}
  },
  "CredentialsProvider": {
    "CognitoIdentity": {
      "Default": {
        "PoolId": "xxxxxx",
        "Region": "ap-northeast-1"
      }
    }
  },
  "CognitoUserPool": {
    "Default": {
      "PoolId": "xxxxxx",
      "AppClientId": "xxxxxx",
      "AppClientSecret": "",
      "Region": "ap-northeast-1"
    }
  },
  "Auth": {
    "Default": {
      "OAuth": {
        "WebDomain": "cognito-auth.xxxxxx,
        "AppClientId": "xxxxxx",
        "SignInRedirectURI": "xxxxxx://",
        "SignOutRedirectURI": "xxxxxx://",
        "Scopes": ["openid"],
        "responseType": "code"
      }
    }
  }
} 

amplifyconfiguration.json

{
  "UserAgent": "aws-amplify-cli/2.0",
  "Version": "1.0",
  "auth": {
    "plugins": {
      "awsCognitoAuthPlugin": {
        "CredentialsProvider": {
          "CognitoIdentity": {
            "Default": {
              "PoolId": "xxxxxx,
              "Region": "ap-northeast-1"
            }
          }
        },
        "CognitoUserPool": {
          "Default": {
            "PoolId": "xxxxxx",
            "AppClientId": "xxxxxx",
            "AppClientSecret": "",
            "Region": "ap-northeast-1"
          }
        },
        "Auth": {
          "Default": {
            "OAuth": {
              "WebDomain": "cognito-auth. xxxxxx",
              "AppClientId": "xxxxxx",
              "SignInRedirectURI": "xxxxxx://",
              "SignOutRedirectURI": "xxxxxx://",
              "Scopes": ["openid"],
              "responseType": "code"
            }
          }
        }
      }
    }
  }
} 

AndroidManifestは以下のようにしておきます。

schemejsonファイル内で指定した SignInRedirectURI と同じにします。

AndroidManifest.xml

<application>
   <activity
        android:name=".MainActivity"
        android:launchMode="singleInstance">
        <intent-filter>
           <action android:name="android.intent.action.VIEW" />
           <category android:name="android.intent.category.DEFAULT" />
           <category android:name="android.intent.category.BROWSABLE" />
          <data android:scheme="xxxxxx" />
        </intent-filter>
   </activity>
・・・
</application>

MainActivty.kt

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Amplify初期化
     try {
          Amplify.addPlugin(AWSCognitoAuthPlugin())
          Amplify.configure(applicationContext)
        } catch (error: AmplifyException) {
          Timber.e("Could not initialize Amplify $error")
        }
・・・
}

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
     if (intent.data != null && "xxxxxx" == intent.data!!.scheme) {
        Amplify.Auth.handleWebUISignInResponse(intent)
      }
}

// Sign in with web UIの呼び出し
private fun loginApple() {
    Amplify.Auth.signInWithWebUI(
        this,
        { result: AuthSignInResult -> {
              val provider = result.nextStep.additionalInfo?.get("provider")
              val token = result.nextStep.additionalInfo?.get("token")
    // 必要なログイン処理
    ・・・
            }
        },
        { error: AuthException -> Timber.e("AuthException $error") }
      )
}

Sign in with web UI用の呼び出し↓後、appleログイン処理に成功したらMainActivityがsingleInstanceで起動されます。

f:id:nyanyonin:20200703122909p:plain:w250

参考文献

https://aws.amazon.com/jp/blogs/aws/new-aws-amplify-libraries-for-android-and-ios/

何か間違っていること等ありましたら遠慮なくご指摘お願いします。