AWS Amplify に関する情報を集約するページ
2022/06 現在、@auth ディレクティブを用いて以下の 6 通りのルールを指定できる
see: Authorization strategies, Setup authorization rules
# API キーによる認証 type Post @model @auth(rules: [{ allow: public }]) { id: ID! content: String! } # IAM による認証(Unauth/Auth どちらのロールでも適切な権限を持っていればアクセス可能) type Post @model @auth(rules: [{ allow: public, provider: iam }]) { id: ID! content: String! } # IAM による認証(Auth ロールでのみアクセス可能) type Post @model @auth(rules: [{ allow: private }]) { id: ID! content: String! } # CUP/oidc による認証 # Post モデルには owner フィールドが自動的に定義され、そのフィールドの値と一致したユーザーのみアクセス可能 # ディレクティブのパラメタにて ownerField を指定することも可能 # ownerField が [String] である場合、ユーザーと一致する値があった際にアクセス可能 type Post @model @auth(rules: [{ allow: owner }]) { id: ID! content: String! } # CUP/oidc のユーザーグループベースの認証 # Post モデルには groups フィールドが自動的に定義され、そのフィールドの値と一致したグループに属するユーザーのみアクセス可能 # ディレクティブのパラメタにて groupsField を指定することも可能 type Post @model @auth(rules: [{ allow: groups }]) { id: ID! content: String! } # カスタム認証 # amplify update 時に対応する Lambda 関数の指定もしくは新規作成が可能 type Post @model @auth(rules: [{ allow: groups }]) { id: ID! content: String! }
Cognito ユーザープール認証を利用している必要がある
type Post @model @auth(rules: [{ allow: owner }]) { id: ID! title: String! owner: String }
@auth ディレクティブの operations プロパティで設定できる。
authorized operations (operations): which operations are allowed for the given strategy and provider. If not specified, create, read, update, and delete operations are allowed. -- read operation: read operation can be replaced with get, list, sync, search, list for a more granular query access API (GraphQL) - Authorization rules - AWS Amplify Docs
指定可能なオペレーションは create, read(get, list, sync, search), update, delete
Amplify API で作成した AppSync GraphQL API で @auth(rules: [{ allow: public, provider: iam }])
により IAM 認証モードを追加している際にはデフォルトでは Amplify によって生成された IAM ロールからのアクセスのみを受け入れる形となっている。
開発中のマネジメントコンソールなどからの動作確認や手元でスクリプトを動かす場合には追加の設定が必要となる。API (GraphQL) - Authorization rules - AWS Amplify Docs に記載があるとおり amplify/backend/api/<api-name>/custom-roles.json
というファイルを作成し以下の内容を追記したのちデプロイすればよい。
{ "adminRoleNames": ["<YOUR_IAM_USER_OR_ROLE_NAME>"] }
下記のような @auth の設定状況下では非ログインユーザーはすべての Record の read が可能だがログインユーザーは owner が自身の sub と一致しているものしか取得できず、結果として非ログインユーザーより権限が弱くなる。
type Record @auth( rules: [ { allow: public, provider: iam, operations: [read] } { allow: owner } ] ) @model(subscriptions: null) { id: ID! description: String }
非ログイン/ログイン状態双方で read を許可しつつ、更新は owner に限りたい場合は下記のように書く
type Record @auth( rules: [ { allow: public, provider: iam, operations: [read] } { allow: private, operations: [read] } { allow: owner } ] ) @model(subscriptions: null) { id: ID! description: String }
{ allow: private }
は Cognito User Pool の JWT トークンを利用したアクセス、{ allow: private, provider: iam }
は Authenticated Role を利用したアクセスという違いがある
amplify codegen init コマンドにてコード生成に関する設定を行ったのちに amplify codegen コマンドを利用してコードを生成できる
see: API (GraphQL) - Configure Lambda resolvers - AWS Amplify Docs
まずLambda 関数自体を用意するため amplify add function
コマンドを実行して下記のような実装を行ったうえでデプロイする。
exports.handler = async function(event, context){ return event.arguments.msg }
その後、スキーマの定義に下記のようなクエリを追加してデプロイすればよい
type Query { echo(msg: String): String @function(name: "echofunction-${env}") }
以下のような GraphQL スキーマがあったとして ListTodos の結果を createdAt など日付順にソートして得たいというシチュエーションはよくある。
type Todo @model { id: ID! title: String! createdAt: AWSDateTime! }
この場合に以下のように @index ディレクティブを活用することによりソートしたクエリ結果を得られる。ただし Todo のすべてのレコードが追加した type フィールドの値を持つようにテーブルのデータを更新する必要はある。
type Todo @model { id: ID! title: String! type: String! @index(name: "todosByCreatedAt", queryField: "listTodosOrderByCreatedAt", sortKeyFields: ["createdAt"]) createdAt: AWSDateTime! }
amplify add function
コマンドで追加した Lambda 関数は手軽に TypeScript で実装できる状態にできる。手順の詳細は Functions - Build options - AWS Amplify Docs に記載されている。
すべての手順はおおまかに次のようなものとなる
package.json
にトランスパイルを行うスクリプトを追加するtsconfig.json
を配置するsee: Functions - Build options - AWS Amplify Docs
// package.json { "scripts": { "amplify:generateReport": "cd amplify/backend/function/generateReport && tsc -p ./tsconfig.json && cd -" }, } // tsconfig.json { "compilerOptions": { "allowSyntheticDefaultImports": true, "lib": ["dom", "esnext"], "module": "commonjs", "moduleResolution": "node", "skipLibCheck": true, "resolveJsonModule": true, "outDir": "./src", "baseUrl": "./", "rootDir": "./lib", "paths": { "src": ["./lib"] } } }
see: 環境に応じたappsync-clientセットアップ
Logger の基本的な利用方法については Utilities - Logger を参照。Amplify JavaScript の Logger は Provider を指定することにより追加の処理を行うことができる。Provider は packages/core/src/Providers に配置してある。
ウェブ界隈でエンジニアとして労働活動に励んでいる @gomi_ningen 個人のブログです