使用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。
其他方面默认即可。
确认角色
验证/非验证角色
我打算确认是否正确设置了与”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)
请原谅这次使用非常简单的架构和应用。
源代码
这边是3号。
質問者问道:“难道需要手动做吗?!”之后没有回复了…
原因很明显,GRAPHQL_AUTH_MODE是一个字符串枚举类型,当尝试将字符串输入其中时会报错。
因为AWS资源已经不存在了,所以即使克隆也无法进行实际的API操作。