3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Amplify の AppSync で Cognito の所属グループに基づく認証処理を実装する

Last updated at Posted at 2021-11-30

本記事について

Amplify の AppSync で、Cognito の所属グループに基づく認証処理を挟む方法について記載します。
具体的には、当該の Cognito User が、"Admin"という名前のグループに入っている場合のみ、AppSync の Query や Mutation 操作ができるようにする 方法について記載をします。

補足

Amplify の勉強時のメモを公開するものです。
私自身、勉強途中で理解が浅い部分もあります。
記載している方法は、必ずしも適切な方法ではないかもしれません。その旨ご理解ください。
メモレベルの内容ですが、後続の方のお役に立てれば幸いです。

想定ケース

以下のような GraphQL スキーマを仮定します。

/amplify/backend/api//schema.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 リゾルバーと呼ばれる機能です。

ここでは、String型の user を引数にして、 functionA-${env}という名前の Lambda function をキックしています。
返り値はString型です。

**ここで、

  1. Cognito の所属グループが "Admin" であるユーザが、
  2. 引数に自分の名前を入れた時のみ、
    この 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

コピー後のリゾルバーを、以下のように書き換えます。(必要に応じて変更してください)

Mutation.functionA.req.vtl
## [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 で認証を実現する方法はいろいろとありそうです。
以下、お役立ちそうなリンクをご参考まで。

3
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?