🚉

Amplifyを使ってログイン要否混在のAPI(AppSync)を立ち上げる手順

2021/06/01に公開
8

この記事は何

  • Amplifyを使ってAPI(GraphQL)を構築する際に、ユーザ認証が必要な機能と不要な機能が混在するケースがあるかと思います。
  • 例えばこちらのサイトの場合、お気に入り機能はユーザ認証が必要ですが、その他のコンテンツは誰でも閲覧できるようにしておきたいと考えると、一つのGraphQL APIの中で、参照権限の使い分けをしたくなってきます。
  • ベストプラクティスかどうかは分からないですが、下記の方法で実現可能ですので、設定方法を残しておきます。 ※Amplify CLIだけで完結させることができておらず、一部AWSコンソールから手動で修正をかける方法になります。

環境構築

  • Amplify CLIを導入して、configの設定、initなどは済んでいるものとして、AuthおよびAPIをプロジェクトに導入します。
  • ポイントは、Authにおいて allow unauthenticated loginsを有効にすることと、APIにおいて認証方法にIAMとCognitoUserPoolの両者を許可することです。
    • 認証が必要な機能はCognitoUserPoolを使います
    • 認証が不要な機能はIAMを使います
      • 認証が不要な機能にはAPI secret keyを使うことも可能ではありますが、有効期限があり、管理が現実的では無いと思うので、選択肢から除外しました。

Authの設定

 ? Do you want to use the default authentication and security configuration?
 -> Manual configuration
 ? Select the authentication/authorization services that you want to use: 
 -> User Sign-Up, Sign-In, connected with AWS IAM controls (Enables per-user Storage features for images or other content, Analytics, and more)
 ? Please provide a friendly name for your resource that will be used to label this category in the project: 
 -> ***********************
 ? Please enter a name for your identity pool.  
 -> ***********************
 ? Allow unauthenticated logins? (Provides scoped down permissions that you can control via AWS IAM) 
 -> Yes
 ? Do you want to enable 3rd party authentication providers in your identity pool?
 -> No (Yesでも良い)
 ? Please provide a name for your user pool:
 -> **********************
 ? How do you want users to be able to sign in? 
 -> Username (何でも良い)
 ? Do you want to add User Pool Groups?
 -> No (何でも良い)
 ? Do you want to add an admin queries API?
 -> No (Yesでも良い)
 ? Multifactor authentication (MFA) user login options:
 -> OFF (何でも良い)
 ? Email based user registration/forgot password:
 -> Enabled (Requires per-user email entry at registration)
 ? Please specify an email verification subject:
 -> (何でも良い)
 ? Please specify an email verification message:
 -> (何でも良い)
 ? Do you want to override the default password policy for this User Pool? Yes
 Enter the minimum password length for this User Pool:
 -> (何でも良い)
 ? Select the password character requirements for your userpool:
 -> (何でも良い)
 ? What attributes are required for signing up?
 -> (何でも良い)
 ? Specify the app's refresh token expiration period (in days):
 -> (何でも良い)
 ? Do you want to specify the user attributes this app can read and write?
 -> (何でも良い)
 ? Specify read attributes:
 -> (何でも良い)
 ? Specify write attributes:
 -> (何でも良い)
 
 Do you want to enable any of the following capabilities? 
 ? Do you want to use an OAuth flow?
 -> No (何でも良い)
 ? Do you want to configure Lambda Triggers for Cognito?
 -> No (何でも良い)

APIの作成

? Please select from one of the below mentioned services:
-> GraphQL
? Provide API name:
-> ************
? Choose the default authorization type for the API
-> IAM
? Do you want to configure advanced settings for the GraphQL API
-> Yes, I want to make some additional changes.
? Configure additional auth types?
-> Yes
? Choose the additional authorization types you want to configure for the API
-> Amazon Cognito User Pool

Cognito UserPool configuration
Use a Cognito user pool configured as a part of this project.

? Enable conflict detection?
-> No (Yesでも良い)
? Do you have an annotated GraphQL schema?
-> No (Yesでも良い)
? Choose a schema template
-> (何でも良い)

GraphQL Schemaの作成

下記の例を参照下さい。

注釈:

  • notNeedAuthの方にも念のためuserPoolsを設定していますが、なくても動作すると思います(未検証)。
  • notNeedAuthの方で、iamの方もprivateにしていますが、publicにしても問題ないかもしれません。私が開発していた際はiamでpublicは指定できなかったと思うのですが、本記事執筆時点ではpublicを指定できるようになっていました。
type notNeedAuth @model
  @key(fields:["id"])
  @auth(rules: [
    { allow: private, provider: iam, operations: [read] }
    { allow: private, provider: userPools, operations: [read] }
  ]){
  id: ID!
}

type NeedAuth @model
  @key(fields:["id])
  @auth(rules: [{ allow: owner, provider: userPools }]){
  id: ID!
}

適宜、公式ドキュメントを参照下さい。
https://docs.amplify.aws/cli/graphql-transformer/auth

【重要】APIのUpdate(※6/18追加)

上記例のようにプロジェクトに必要なauthディレクティブを含んだschemaを作成した後、変更を反映するためにamplify update apiを実行する必要があります。
設定内容自体は変える必要は無いのですが、この手順を踏むことで作成したschemaがコンパイルされ、必要なリソース(policy等も)作成されるようです。

AWSコンソールでの編集(※6/18順序変更)

Auth, APIをamplify pushしてバックエンドを構築した後の手順です。

  1. IAM -> ポリシー に進む
  2. Amplify CLIが生成したgraphQL用のポリシーがあるので、そのARNをコピーする。命名ルールはamplify-(ProjectName+random)-api(ApiName+random)-AuthRolePolicy(some numbers)
  3. IAM -> ロール に進む
  4. 同じくAmplify CLIが生成したロールがあるので、そのうちunauthRoleに2.のポリシーをアタッチする。

この手順により、IAMで認証した場合、authUserとunauthUserで同じ権限を持つことができる。

おわりに

amplifyの開発はまだまだon goingということもあり、頻繁に仕様変更が入っています。もし情報の変更など気が付かれましたら、コメントを頂けると幸いです。こちらの記事に反映していきます。

GitHubで編集を提案

Discussion

batayanbatayan

すみません、こちらの記事に書かれた手順で push した後、policy を探しましたが、見つかりませんでした。
https://zenn.dev/foxtail88/articles/9580ec6c5c2164#awsコンソールでの編集
何かご存知ないでしょうか?

tenkohtenkoh

コメントありがとうございます。
差し支えなければ、ご使用されているamplify cliのバージョンを教えて頂けますか??

tenkohtenkoh

手順の不足箇所を発見したので、記事を修正します…!少々お待ち下さい。

tenkohtenkoh

修正完了しました。再度お試しいただけますか?

当方、Amplify cli v4.47.1 で、上記手順で環境構築完了まで確認できました。

batayanbatayan

試してみましたところ、一点

type NeedAuth @model
  @key(fields:["id])
  @auth(rules: [{ allow: owner, provider: userPools }]){
  id: ID!
}

こちらの fields:["id] ここで閉じダブルクォーテーションが抜けていまして、コンパイルが通らなかったです。他は大丈夫でした。
amplify push しましたら policy が作成されていました。改めましてありがとうございました。

batayanbatayan

たびたび申し訳ありません。
AppSync をクライアントから実行しますと 401 エラーが返ってきます。認証が通らないです。
Cognito にユーザープールが作成されていない、というところまでは確認しました。
(修正)Cognito の ID プールは作成されていました。こちらの ID プールの連携がうまくいっているか確認中です。
他、どういったところを確認すべきかも分かっていないです。御指南いただけますと大変ありがたいです。
差し当たってご報告いたします。私の方でも何かまた判明しましたら、そこからまたやり取りをさせていただきたいです。

batayanbatayan

すみません、こちら、原因分かりました。自動生成されたポリシーには notNeedAuth の物しか allow されていませんでした。実行させたい API を明示的に指定しましたら、無事、認証が通って実行させることができました。今はまた別のエラーも出ていますが、差し当たり認証とは関係なさそうではあります。こちら解決です。
大変申し訳ありませんでした。

batayanbatayan

ブログ、大変参考になりました。迅速な対応をいただき、ありがとうございます。
amplify のバージョンは 5.0.0 です。
再度試してみてまた報告させていただきます。ありがとうございました。