本記事について
Amplify の AppSync で、Cognito の所属グループに基づく認証処理を挟む方法について記載します。
具体的には、当該の Cognito User が、"Admin"という名前のグループに入っている場合のみ、AppSync の Query や Mutation 操作ができるようにする 方法について記載をします。
補足
Amplify の勉強時のメモを公開するものです。
私自身、勉強途中で理解が浅い部分もあります。
記載している方法は、必ずしも適切な方法ではないかもしれません。その旨ご理解ください。
メモレベルの内容ですが、後続の方のお役に立てれば幸いです。
想定ケース
以下のような GraphQL スキーマを仮定します。
### 1
type Mutation{
functionA(
user: String!
): String @function(name: "functionA-${env}")
}
### 2
type User
@model
@auth(rules: [{ allow: owner, ownerField:"user", provider: userPools }])
@key(fields: ["user"]) {
user: String!
address: String!
email: String!
}
###1
に記載している type Mutation functionA
は、Amplify の Lambda リゾルバーと呼ばれる機能です。
- Lambda リゾルバーについてはこちら
ここでは、String型の user
を引数にして、 functionA-${env}
という名前の Lambda function をキックしています。
返り値はString型です。
**ここで、
- Cognito の所属グループが "Admin" であるユーザが、
- 引数に自分の名前を入れた時のみ、
この Mutation を操作できるように制限をかけたいと仮定します。**
※ Lambda リゾルバーでも、@auth
ディレクティブを使うことで認証を追加することができます。しかし、Cognito グループに応じた認可や、引数の値に応じた認可はできません。(そのはず)
※ ### 2
のように、@model
を伴う通常のスキーマの場合、@auth
ディレクティブ の ownerField
を用いることで引数の値に応じた認可は実現できます。しかし Cognito グループに応じた認可はできません。(そのはず)
実装手順
schema.graphql
を作成後に、$ amplify push
を実行すると、
以下のパスに、リクエストマッピングテンプレートのリゾルバーが作成されています。
<project-root>/amplify/backend/api/<api-name>/build/resolvers
このうち、認証を追加したい処理のもののみを以下のパスにコピーします。
<project-root>/amplify/backend/api/<api-name>/resolvers
コピー後のリゾルバーを、以下のように書き換えます。(必要に応じて変更してください)
## [Start] Stash resolver specific context.. **
# set( $adminRole = "Admin" ) ## Admin グループを設定**
# set( $myRole = $ctx.identity.groups[0] ) ## 自分の所属グループを取得**
# set( $cognitoUserName = $ctx.identity.username ) ## ログインしているCognitoのユーザ名を取得**
# set( $inputUserName = $ctx.args.user ) ## 引数userに入力しているユーザ名を取得**
## 自分の所属グループが"Admin"ではない、もしくは、Cognitoの認証情報と引数userが一致しない場合は処理を終了
# if( $myRole != $adminRole || $cognitoUserName != $inputUserName )
$util.unauthorized()
# else
$util.qr($ctx.stash.put("typeName", "Mutation"))
$util.qr($ctx.stash.put("fieldName", "functionA"))
{}
# end
## [End] Stash resolver specific context.. **
上記サンプルの処理内容は、## **
でくくっているコメントを参照してください。
意図しないユーザからの操作について、途中で処理を終了して、リクエストされた Mutation が実行されないようにしています。
最後に $ amplify push
を再度することで、クラウド上のリソースに本リゾルバーの内容が反映されます。
デプロイが完了すると、期待通りに認証がかかった状態になっているはずです。
お役立ちサイト
AppSync のリゾルバーは奥が深くて難しいです。。。
私の記事と同じものは見当たりませんでしたが、AppSync で認証を実現する方法はいろいろとありそうです。
以下、お役立ちそうなリンクをご参考まで。