我的Web应用程序在前端使用React,在后端使用Flask。
我想添加AWS Cognito进行用户管理。根据{{3}},这只需要在前端包装export
语句即可,即更改一行
export default App;
在App.js
文件中(定义了主应用程序React组件)到
export default withAuthenticator(App, true);
加上所需的import
语句。
这项微不足道的更改使我获得了生产中使用的任何合理的Web应用程序所需的所有以用户为中心的功能,例如
包括
问题:我不知道如何将其与后端集成。
方法:(我认为应该如此)
currentAuthenticatedUser()
(JWT)我已经实现了通常的Flask /login
或/logout
请求处理程序以及一个login_required
装饰器,并且还传递了JWT和解码声明,效果很好; 但是,我看不到前端应在哪里通知后端有关用户登录的信息。
我尝试使用JSON Web Token进行此操作,但这有很多缺点:
对于初学者来说,由用户登录触发的AWS lambda函数必须能够访问后端,因此它必须是公开可用的。出于安全原因,我实际上希望后端仅对前端可见/可访问。另外,在开发过程中,我在MacBook的Docker容器中同时运行前端和后端。这种方法迫使我至少在云中运行后端。
最大的问题是它不起作用:从后端的角度来看,来自前端和Cognito的请求是在单独的会话中进行的,因此,即使用户使用Cognito(通过前端),然后Cognito会通过lambda触发器通知后端有关此登录的信息,从后端到后端的任何后续请求(从后端到后端的请求)都不会与后端和Cognito之间的(经过身份验证的)会话相关联,因此未经身份验证。
好吧,除了巨大的缺点和不起作用的事实外,lambda触发方法也让人感到完全过头了。
更新:我不知道为什么我以前没有看到它,但是Amplify文档中有一个Cognito Post Authentication Lambda Trigger,可以准确地说明如何自定义withAuthenticator
。但是,我不想像示例中那样覆盖render()
,而是覆盖signIn()
(或者我相信)。我已经成功实现了将代码发送到带有适当标头的http://mybackend.mydomain.com/login
以便登录后端的代码,但是我似乎无法弄清楚在哪里/如何调用该代码。
我从上面链接的Amplify文档中复制了代码,查看了SignIn
section和{{rendered /“ built”?)版本在我的本地源代码文件夹中的{{ 1}},并尝试了以下方法:
node_modules/aws-amplify-react/dist/Auth/SignIn.js
但是所有这些使我得到的是一个空白页面,并且日志中没有任何消息。
新问题:我如何实现class MySignIn extends SignIn {
async signIn() {
console.log('MySignIn.signIn() start');
super.signIn()
.then(data => console.log(data))
.catch(err => console.log(err));
console.log('MySignIn.signIn() end');
}
}
以便完成所有MySignIn
的工作,但是成功登录后,我还需要其他工作吗?>
非常感谢您的考虑! :-)
答案 0 :(得分:1)
我检查了代码,signIn
函数似乎很难扩展,因为它不返回任何内容,因此使用super
和then
没有意义,因为解析函数是'不会接收任何数据。这就是为什么您的日志为空。要使用它,您需要从头开始重新定义它。
您可以做的是重新实现changeState
方法本身,在这种情况下,您可以只调用父方法,然后再做任何您想做的事。
但是仅扩展任何Auth
组件就有一个问题,因为如果您想重新实现render
或showComponent
函数 对它们进行子类化是因为父级对象(因为父级对象现在被隐藏了)不会返回任何内容。 (尽管在示例中render
函数已被明确地重新定义,但这可能是他们应该在文档中清除的。)
在不返回空白页的情况下调用父类的showComponent
方法的一种简单方法是从每个组件接收的隐藏组件列表中删除父类。
因此,与changeState
方法的扩展一起,看起来像这样:
class MySignIn extends SignIn {
showComponent(theme) {
const signIn = this.props.hide.indexOf(SignIn)
this.props.hide.splice(signIn, 1) // make sure SignIn is not hidden
return super.showComponent(theme) // call showComponent from SignIn
}
changeState(state, data) {
super.changeState(state, data)
if (state !== 'signedIn') return
console.log(data)
// make the request to the backend
}
}
现在,您可以像在文档中显示的那样完全通过MySignIn
。
请记住,更改props
应该是一种反模式,但是我还没有找到不涉及重新定义showComponent
(或更糟的是{{1 }})方法,因为它是在父级中寻找的。 p>
PR的想法可能是使这些方法(例如render
)更易于扩展。
之所以无法实现,是因为在实际实例化组件时,signIn
属性会被覆盖。
另一种选择是将函数传递给onStateChange
作为登录组件的道具,并检查onStateChange
状态,如下所示:
signedIn
根据您对function onStateChange(state, data) {
if (state !== 'signedIn') return
console.log(data)
// do the request to the backend here
}
的自定义
withAuthenticator