AWS Amplify + Cognito + React で owner に制限した CRUD を実装時に「Not Authorized to access createTodo on type Mutation」が出る場合の対処法

2022.04.25

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AWS Amplifyによる実装時にNot Authorized to access createTodo on type Mutationというエラーに遭遇しました。

背景と現象

AWS Amplify の React のチュートリアルを実装し、Amplifyにデプロイしました。

日本語の記事では、こちらがわかりやすいです。

AWS Amplifyの公式チュートリアルでToDoリストアプリ(React)をデプロイしてみた | DevelopersIO

さて、このチュートリアル終了時点のToDoリストアプリは

  • Cognitoの認証が通ったユーザだけがToDoリストを表示、ToDoアイテムを作成できる
  • ユーザ毎に、当該ユーザが作ったToDoアイテムだけが表示されるようにはなっていない(全アイテムが表示される)

という状態です。

そこで、ユーザ毎に、当該ユーザが作ったToDoアイテムだけを表示するようにしたいと思い、方法を調査しました。

GraphQLのリファレンス API (GraphQL) - Authorization rules - AWS Amplify Docs によると、@authディレクティブをAPIのスキーマ amplify/backend/api/YOUR_API_NAME/schema.graphql に追加するだけでよさそうでした。

- type Todo @model {
+ type Todo @model @auth(rules: [
+   { allow: owner }
+ ]) {
    id: ID!
    name: String!
    description: String
  }

{ allow: owner }としているので、ToDoアイテムの作成者だけがCRUDできる設定です。

これで、amplify publishを実行し、バックエンドとフロントエンドの双方のコードをスキーマから自動生成してデプロイしました。

$ amplify publish

? Are you sure you want to continue? Yes
? Do you want to update code for your updated GraphQL API Yes
? Do you want to generate GraphQL statements (queries, mutations and subscription) based on your schema types? This will overwrite your current graphql queries, mutations and subscriptions Yes

この状態から、ToDoリストアプリを実行してみると、ログイン後のToDoアイテムの追加(Create)で次のエラーに遭遇し、ToDoアイテムが追加できませんでした。

Not Authorized to access createTodo on type Mutation

解法

authMode: "AMAZON_COGNITO_USER_POOLS"をGraphQL APIを呼び出す時に指定することで解決できました。

API (GraphQL) - Configure authorization modes - JavaScript - AWS Amplify Docs にならって、src/App.jsの GraphQL API 呼び出し箇所を次のように書き換えました。

ToDoアイテムのfetch部分。

-       const todoData = await API.graphql(graphqlOperation(listTodos))
+       const todoData = await API.graphql({
+         query: listTodos,
+         authMode: 'AMAZON_COGNITO_USER_POOLS'
+       })

ToDoアイテムの作成部分。

-       await API.graphql(graphqlOperation(createTodo, {input: todo}))
+       await API.graphql({
+         query: createTodo,
+         variables: {input: todo},
+         authMode: 'AMAZON_COGNITO_USER_POOLS'
+       })

AMAZON_COGNITO_USER_POOLS がamplify authモジュールに追加されていないと別のエラーになりますので、その場合は次のコマンドを実行しておきます。1

$ amplify api update

? Select from one of the below mentioned services: GraphQL
? Select a setting to edit Authorization modes
? Choose the default authorization type for the API API key
✔ Enter a description for the API key: · demo
✔ After how many days from now the API key should expire (1-365): · 7
? Configure additional auth types? Yes
? Choose the additional authorization types you want to configure for the API Amazon Cognito User Pool

参考


  1. チュートリアルに沿って実装すると、default authorization typeはAPI Keyになるため、Amazon Cognito User Poolをadditional auth typesとして追加しています。最初からdefault authorization typeをAmazon Cognito User Poolにしても良いと思います。