Amplifyを使っていて、未認証(未ログイン)ユーザでAppSyncを接続しようとしたらno current userと出て、接続することができませんでした。解決するのにかなりつまったので、残しておきます。
実施する前の状態
- すでにAmplifyは構築されており、Auth, API(AppSync)も構築済み
- Authの認証方法はAMAZON_COGNITO_USER_POOLS
実施後の状態
- Authの認証方法はAWS_IAM
- 認証ユーザと未認証ユーザでIAMを設定
- 認証ユーザはAppSyncの全権限を持つPolicyが割り当てられている
- 未認証ユーザはAppSyncのQueryとSubscriptionの権限を持つPolicyが割り当てられている
手順
IAM認証にし、認証されていないIDに対してアクセスを有効にする
$ amplify update auth
Please note that certain attributes may not be overwritten if you choose to use defaults settings.
You have configured resources that might depend on this Cognito resource. Updating this Cognito resource could have unintended side effects.
Using service: Cognito, provided by: awscloudformation
What do you want to do? Walkthrough all the auth configurations
Select the authentication/authorization services that you want to use: User Sign-Up, Sign-In, connected with AWS IAM controls (Enables per-user Storage features for images or other content, Anal
ytics, and more)
Allow unauthenticated logins? (Provides scoped down permissions that you can control via AWS IAM) Yes # ここをYesにする
--- (中略) ---
- これでCognitoのフェデレーティッドアイデンティティで認証されていないIDに対してアクセスを有効にするがチェックされます
AppSyncの権限を持つPolicyを作成する
-
<project_root>/amplify/backend/api/<API name>/stacks/
配下にCFnのコードを置くことでPolicyを追加することができます- カスタムリソースを使おうかと思いましたが、AppSyncApiIdはapi配下でないと取得できないので、こちらである必要があります
- 以下のようにIAMPolicy.jsonを作成しています
project_root/amplify/backend/api/API_name/stacks/IAMPolicy.json
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "AppSync GraphQL Policy",
"Metadata": {},
"Parameters": {
"AppSyncApiId": {
"Type": "String",
"Description": "The id of the AppSync API associated with this project."
},
"env": {
"Type": "String",
"Description": "The environment name. e.g. Dev, Test, or Production",
"Default": "NONE"
},
"authRoleName": {
"Type": "String"
},
"UnauthRoleName": {
"Type": "String"
}
},
"Resources": {
"AuthAppSyncGraphQLPolicy": {
"Type": "AWS::IAM::ManagedPolicy",
"Properties": {
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"appsync:GraphQL"
],
"Resource": [
{
"Fn::Sub": [
"arn:aws:appsync:${AWS::Region}:${AWS::AccountId}:apis/${apiID}/*",
{
"apiID": {
"Ref": "AppSyncApiId"
}
}
]
}
]
}
]
},
"ManagedPolicyName": {
"Fn::Join": [
"-",
[
"AuthAppSyncGraphQLPolicy",
{
"Ref": "env"
}
]
]
},
"Roles": [
{
"Ref": "authRoleName"
}
]
}
},
"UnauthAppSyncGraphQLPolicy": {
"Type": "AWS::IAM::ManagedPolicy",
"Properties": {
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"appsync:GraphQL"
],
"Resource": [
{
"Fn::Sub": [
"arn:aws:appsync:${AWS::Region}:${AWS::AccountId}:apis/${apiID}/types/Query/*",
{
"apiID": {
"Ref": "AppSyncApiId"
}
}
]
},
{
"Fn::Sub": [
"arn:aws:appsync:${AWS::Region}:${AWS::AccountId}:apis/${apiID}/types/Subscription/*",
{
"apiID": {
"Ref": "AppSyncApiId"
}
}
]
}
]
}
]
},
"ManagedPolicyName": {
"Fn::Join": [
"-",
[
"UnauthAppSyncGraphQLPolicy",
{
"Ref": "env"
}
]
]
},
"Roles": [
{
"Ref": "UnauthRoleName"
}
]
}
}
},
"Outputs": {
"EmptyOutput": {
"Description": "An empty output. You may delete this if you have at least one resource above.",
"Value": ""
}
}
}
- AuthRoleとUnauthRoleの定義をparameters.jsonに追加します
project_root/amplify/backend/api/API_name/parameters.json
{
--- (中略) ---
"authRoleName": {
"Ref": "AuthRole"
},
"UnauthRoleName": {
"Ref": "UnauthRole"
}
}
動作確認
-
amplify push
して問題なく、動作することを確認します - IAMでPolicyが作成されていることが確認できます
- AuthRoleとUnauthRoleが上記で作成したPolicyが紐づいていることが確認できます
- Role名はCognitoのフェデレーティッドアイデンティティで確認できます