AmplifyでPublicアクセス認証方式を追加する。(2021年3月時点)
スキーマの修正
例えば以下のようなスキーマがあるとする。
これはAMAZON_COGNITO_USER_POOLSを使用してデータ作成者(Owner)のみデータの更新ができ、それ以外は読み込み(read)のみ可能という状態である。
type Product
@model
@auth(rules: [{ allow: owner, operations: [create, delete, update] }]) {
id: ID!
name: String!
description: String
}
この状態だとログインしていないゲストユーザーではProductデータのreadしようとすると"No Current User"というエラーが出てしまう。
ログインしていない状態のユーザー(ゲストユーザー)でもこのデータにアクセスできるようにするには以下のpublicアクセスを許可する設定を追加する。
type Product
@model
@auth(rules: [
{ allow: owner, operations: [create, delete, update] },
{ allow: public, operations: [read] } # unauthenticated users can read
]) {
id: ID!
name: String!
description: String
}
PublicアクセスはAPI_KEYかAWS_IAMを使用したアクセスになる。
API_KEYの使用は手軽だが、最大でも365日毎に手動で新しいAPI_KEYの作成を行わなければいけない。そのためAWS_IAMを使用する設定を追加する。
providerの記述がないとデフォルトではAPI_KEYを使用しようとする。
type Product
@model
@auth(rules: [
{ allow: owner, operations: [create, delete, update] },
{ allow: public, provider: iam, operations: [read] } # unauthenticated users can read
]) {
id: ID!
name: String!
description: String
}
バックエンドの修正
AWS_IAMを使用するためにバックエンドをCLIを使用して修正する。
$ amplify update api
? Please select from one of the below mentioned services: GraphQL
? Select from the options below Walkthrough all configurations
? Choose the default authorization type for the API Amazon Cognito User Pool
Use a Cognito user pool configured as a part of this project.
? Do you want to configure advanced settings for the GraphQL API Yes, I want to make some additional changes.
? Configure additional auth types? Yes
? Choose the additional authorization types you want to configure for the API IAM
? Configure conflict detection? No
最後に設定変更を反映する
$ amplify push
これでバックエンドの修正は完了。
アプリロジックの修正
これで完成かと思いきや、最後にアプリ側で修正が1点ある。
Publicアクセスを許可するデータ取得の前に以下のようにAmplify.configureを修正するロジックを挟む必要がある。
AWS_IAMがバックエンドで使用可能となっていても、AmplifyはデフォルトでAMAZON_COGNITO_USER_POOLSを使用してしまい"No Current User"が返されてしまう。
そのため、アクセス方式の切り替えロジックが必要となる。
// isAuthenticated: ログインしているかの変数
if (isAuthenticated) {
Amplify.configure({
"aws_appsync_authenticationType": "AMAZON_COGNITO_USER_POOLS",
});
} else {
Amplify.configure({
"aws_appsync_authenticationType": "AWS_IAM",
});
}
listProduct(); // データ取得
以上でPublicアクセスができるはずである。
何か他の方法があれば、情報提供いただけると助かります。
お読みいただきありがとうございました。
Discussion