LoginSignup
3
1

More than 3 years have passed since last update.

Amplifyのschema.graphqlの@authでカスタム属性を使う方法

Last updated at Posted at 2020-12-30

困ったこと

下記のように、Amplifyのschema.graphqlの権限にカスタム属性を使おうとしても使えなかった。

schema.graphql
type Article
@model
@auth(rules:[
  {allow: owner, identityClaim: "custom:company", ownerField: "companyId", operations: [read]}
])
{
  id: ID!
  title: String
  body: String
  companyId: ID!
  createdAt: AWSDateTime!
  updatedAt: AWSDateTime!
}

解決法

Amplify(AppSync)でCognito User Poolのカスタム属性を使いたい場合は、GraphQL APIリクエスト時のAuthorizationヘッダーにIDトークンを入れる必要がある。(デフォルトではアクセストークンが入る)
実装としてはAmplify.configure()の引数を下記のように設定するイメージ。

import Amplify, { Auth } from 'aws-amplify'
import awsconfig from '../src/aws-exports'

Amplify.configure(Object.assign({}, awsconfig, {
  API: {
    graphql_headers: async ()=>({
      Authorization: (await Auth.currentSession()).getIdToken().getJwtToken()
    })
  },
}))

懸念点

https://github.com/aws-amplify/amplify-js/issues/1772
上記の公式Issueでも言及されているが、APIリクエスト時のAuthorizationヘッダーにIDトークンを入れるのはセキュリティ上の懸念があるため基本的には非推奨。

代替案

上記懸念点を踏まえて代替案を考える。

代替案① Cognito User PoolのGroupに対象IDを入れる

下記のようにowner指定ではなくgroups指定にして、IDをCognito User PoolのGroupに入れてしまう。

schema.graphql
- {allow: owner, identityClaim: "custom:company", ownerField: "companyId", operations: [read]}
+ {allow: groups, groupsField: "companyId", operations: [read]}

もし、Groupを使って管理者と一般ユーザーを分けたい場合にも、下記のように併記させることで共存することが可能。
もちろん、この場合はcompanyIdに"ADMIN"という文字列が定義されないことが前提となる。

schema.graphql
{allow: groups, groupsField: "companyId", operations: [read]},
{allow: groups, groups: ["ADMIN"], operations: [read, create, update, delete]},

この案を採用する場合にはCognitoの各種上限に注意。

  • 各ユーザーが所属できるグループの最大数: 100
  • ユーザープールごとのグループの最大数: 10,000

これらの条件をクリアできるのであれば採用するメリットはある。

代替案② Lambdaリゾルバーを使う

上記参照URLの通り、Lambda関数を作って、その中でDynamoDB等からユーザー情報と対象IDを取得し、比較することで権限を判定。
自由度の高い方法だが、こうなってくるとREST APIと開発工数的にほぼ変わらないので、一長一短。

3
1
0

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
1