使用AWS Amplify和AppSync AWS_IAM,使非认证用户也能发送查询和变更操作

这篇文章的目标读者

    • AWS AmplifyでAppSyncを使っている。

 

    • GraphQLAPIを公開用にしたい。/非認証ユーザーでも使えるようにしたい。

 

    AppSyncの認証をAPI_KEYでしているが、手動でリフレッシュするのが嫌だ。

首先

如果使用AppSync来公开GraphQL API,就需要以某种方式进行身份验证。
在许多情况下,由于其便捷性,人们倾向于选择API_KEY。
然而,我在查看AppSync文档时发现,

API密钥的有效期最长可设置为365天,从当天起再延长最多365天,延长已存在的有效期。推荐在公开API安全的用例或开发目的中使用API密钥。

据说。
除此之外,根据这个问题,虽然提供了API_KEY的刷新方法,但可能目前只能手动完成。1

除了OPENID_CONNECT认证和AMAZON_COGNITO_USER_POOLS认证外,还有其他选项,但这两种选项都需要进行某种形式的登录。

因此,我們這次將使用AWS_IAM來進行身份驗證,讓非認證用戶能夠進行查詢和變更而不需要使用API_KEY。

理屈 (lǐ qū) – This phrase can be paraphrased as “having a logical argument” or “being logically correct” in Chinese.

1. 將驗證設置為AWS IAM。
2. 然後將未驗證使用者授予Cognito身份池的未認證角色。
3. 對該未認證角色附加查詢和變更的策略。

另外,在amplify中,根据schema的@auth指令,会自动附加相应的策略,生成已认证角色和未认证角色。

环境

    • React 17.0.1

 

    • TypeScript 4.0.3

 

    • aws-amplify 3.3.13

 

    amplify-cli 4.40.1
$ amplify init

前面的设置已经完成,现在我们将继续推荐。

增加资源

增加认证

$ amplify add auth

请添加auth模块。在进行过程中,会出现一个问题:是否允许未经身份验证的登录?(通过AWS IAM可以控制权限范围),请务必选择是。

你想使用默认的身份验证和安全配置吗?(使用箭头键选择)

想要进行详细的设置,所以需要手动配置。

选择您想要使用的身份验证/授权服务:(请使用箭头键)

用户注册、用户登录,与AWS IAM控制相连(为每个用户启用图像或其他内容的存储功能、分析等)

请提供一个友好的名称给你的资源,这个名称将用来标记项目中的这个分类。

任何标签名称 hé

请为您的身份池输入一个名称。

任意的身份池名称 de chí

允许未经身份验证的登录?(通过AWS IAM,提供了权限限制,可由您控制)

是的。

接下来由您决定即可。如果非要说的话,没有第三方认证或OAuth,所以可以选择不需要。

添加API

$ amplify add api

我将创建一个API。

选择 API 的默认授权类型

请在以下选项中选择 IAM 。其他项可以根据需要自行选择。

编辑模式

指令的设置

本次将允许未经认证的用户使用queries和mutation的create。

type Todo
  @model(mutations: { create: "createTodo" }, subscriptions: null)
  @auth(rules: [{ allow: public, provider: iam }]) {
  id: ID!
  name: String!
  description: String
}

在@认证部分是错误的。文档的公共授权栏中有一个示例。根据这个示例,

auth指令可以覆盖指定认证模式的默认提供程序。在上面的示例中,iam被指定为可以代替API密钥,用作Cognito身份池的“未经验证角色”作为公共访问的提供程序。与amplify add auth一起使用时,CLI将自动生成针对“未经验证”角色的范围缩小的IAM策略。

换句话说

允许: 公开: 针对非认证用户
提供者: IAM: 由于目标对象是非认证用户,IAM将授予UnAuthenticated角色。

這表示…

另外,在@model中设置了生成所有查询和仅创建操作的指令,并在推送时自动向生成的UnAuthenticated角色授予这些操作权限。

推 (tuī)

那么

$ amplify push

让我们把代码 push 到云端同时生成 GraphQL 代码。

你希望为你新创建的GraphQL API生成代码吗?

是的。

选择代码生成语言目标

这次为了前端的方便考虑,我们选择了TypeScript。
其他方面默认即可。

确认角色

验证/非验证角色

role-2.png

我打算确认是否正确设置了与”amplify-(项目名称)-(环境名称)-(数字?)-(未经授权/经授权)”相关的角色。也要检查是否正确设置了该角色的策略。

政策

在IAM控制台上,如果在搜索中附加上之前的角色并查看访问权限,我确实认为以下资源已被指定:
– 获取待办事项
– 列出待办事项
– 创建待办事项
到目前为止,后端编辑已经完成了。

前台编辑

我从这里开始编辑前台。

$ yarn add aws-amplify

我假设正在进行这项事情。

//index.tsx
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import Amplify from "aws-amplify";
import config from "./aws-exports";
Amplify.configure(config);

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

//App.tsx
import React from "react";
import API from "@aws-amplify/api";
import * as mutations from "./graphql/mutations";
import * as queries from "./graphql/queries";
import { GRAPHQL_AUTH_MODE } from "@aws-amplify/api-graphql/lib/types";
//TypeSciprtの方は↑に注意

function App() {
  const todoDetails = {
    name: "test",
    description: "test",
  };
  const generateTodo = async () => {
    try {
      await API.graphql({
        query: mutations.createTodo,
        variables: { input: todoDetails },
        authMode: GRAPHQL_AUTH_MODE.AWS_IAM,//TypeScriptの場合のみ それ以外は"AWS_IAM"
      });
    } catch (e) {
      console.error(e);
    }
  };
  const getList = async () => {
    try {
      console.log(
        await API.graphql({
          query: queries.listTodos,
          authMode: GRAPHQL_AUTH_MODE.AWS_IAM,//TypeScriptの場合のみ それ以外は"AWS_IAM"
        })
      );
    } catch (e) {
      console.error(e);
    }
  };

  return (
    <>
      <button onClick={getList}>Query</button>
      <button onClick={generateTodo}>Mutation</button>
    </>
  );
}

export default App;

在使用AWS_IAM认证模式时,不使用graphqlOperation函数。相反地,应该使用另一种方法。

await API.graphql({
      query: queries.listTodo,
      authMode: GRAPHQL_AUTH_MODE.AWS_IAM, //TypeScriptの場合のみ それ以外は"AWS_IAM"
    });

请传入一个包含authMode参数的对象。文档链接在这里。

在这里,如果您在项目中使用TypeScript,请导入名为GRAPHQL_AUTH_MODE的类型,并将authMode设置为GRAPHQL_AUTH_MODE.AWS_IAM。
如果不是的话,请按照文档的方式,将字符串”AWS_IAM”传递即可。
我们目前正在跟进此问题并进行确认。

确认动作 (Confirm action)

スクリーンショット 2020-12-31 15.14.44.png

请原谅这次使用非常简单的架构和应用。

源代码

这边是3号。

質問者问道:“难道需要手动做吗?!”之后没有回复了…

原因很明显,GRAPHQL_AUTH_MODE是一个字符串枚举类型,当尝试将字符串输入其中时会报错。

因为AWS资源已经不存在了,所以即使克隆也无法进行实际的API操作。