将 CognitoUser 存储在缓存中会使他丢失一些属性
Storing CognitoUser in cache make him lose some properties
我目前在我的应用程序中使用 AWS Cognito。
当用户第一次连接他的帐户时,Cognito returns NEW_PASSWORD_REQUIRED 作为挑战,这很好。
我想重定向到用户可以设置新密码的页面,所以我将 Auth.signIn 的响应放在存储中(我尝试了本地存储、会话存储和来自 AWS Amplify 的缓存)但是当我把它放回另一页,它失去了一些属性和 Auth.completeNewPassword returns 错误:'user.completeNewPasswordChallenge is not a function'
Login.js :
try {
var authPromise = Auth.signIn(this.state.email, this.state.password);
authPromise.then((result) => {
console.log(result);
if (result.challengeName === 'NEW_PASSWORD_REQUIRED') {
Cache.setItem("CognitoUser", result);
this.props.history.push("/login/newPassword");
}
else {
this.props.userHasAuthenticated(true);
this.props.history.push("/");
}
});
} catch (e) {
alert(e.message);
this.setState({ isLoading: false });
}
NewPassword.js :
try {
var user = Cache.getItem("CognitoUser");
if (user) {
await Auth.completeNewPassword(user, this.state.newPassword);
this.props.history.push("/");
Cache.removeItem("CognitoUser");
}
} catch (e) {
alert(e.message);
this.setState({ isChanging: false });
}
有什么想法吗?
它是 javascript 所以当你写入你的本地缓存并将你的 result
序列化到 "CognitoUser"
键时,它被存储为一个字符串,之后反序列化将是一个普通的旧 Object
不知道序列化前的原始类型。
原始原因可能是您的 "result" 类型可能公开不可序列化的函数(如果不是 getter,或者 getter 带有参数)。
我建议你把你想要的所有数据调用并存储到单独的键中,稍后重新读取它们。
Cache.setItem("CognitoUser", result);
Cache.setItem("CognitoUser-value-1", result.myFunction1("myArg1"));
Cache.setItem("CognitoUser-value-2", result.myFunction2("myArg2"));
// ..
var user = Cache.getItem("CognitoUser");
var myVal1 = Cache.getItem("CognitoUser-value-1");
var myVal2 = Cache.getItem("CognitoUser-value-2");
如果您使所有上述函数都可序列化,您还可以在 localStorage 中保留一个键 "CognitoUser"
。例如,扩展 result
的类型,添加原型 getter 函数(无参数),每次调用和返回各自的 myFunctionX("myArgX")
函数,这样它们就会出现在 JSON.stringify进程。
我的工作,
所以这个问题困扰了我一段时间。 Amplify Cache 似乎不起作用,缓存用户名和密码是个坏主意,但是我的解决方法只是在 Require-New-Password 表单中包含用户名和密码,所以我有 4 个输入,而不仅仅是 newPassword 和 confirmPassword现在是用户名、旧密码、新密码和确认密码。
https://github.com/aws-amplify/amplify-js/issues/1715#issuecomment-642733574
我目前在我的应用程序中使用 AWS Cognito。
当用户第一次连接他的帐户时,Cognito returns NEW_PASSWORD_REQUIRED 作为挑战,这很好。
我想重定向到用户可以设置新密码的页面,所以我将 Auth.signIn 的响应放在存储中(我尝试了本地存储、会话存储和来自 AWS Amplify 的缓存)但是当我把它放回另一页,它失去了一些属性和 Auth.completeNewPassword returns 错误:'user.completeNewPasswordChallenge is not a function'
Login.js :
try {
var authPromise = Auth.signIn(this.state.email, this.state.password);
authPromise.then((result) => {
console.log(result);
if (result.challengeName === 'NEW_PASSWORD_REQUIRED') {
Cache.setItem("CognitoUser", result);
this.props.history.push("/login/newPassword");
}
else {
this.props.userHasAuthenticated(true);
this.props.history.push("/");
}
});
} catch (e) {
alert(e.message);
this.setState({ isLoading: false });
}
NewPassword.js :
try {
var user = Cache.getItem("CognitoUser");
if (user) {
await Auth.completeNewPassword(user, this.state.newPassword);
this.props.history.push("/");
Cache.removeItem("CognitoUser");
}
} catch (e) {
alert(e.message);
this.setState({ isChanging: false });
}
有什么想法吗?
它是 javascript 所以当你写入你的本地缓存并将你的 result
序列化到 "CognitoUser"
键时,它被存储为一个字符串,之后反序列化将是一个普通的旧 Object
不知道序列化前的原始类型。
原始原因可能是您的 "result" 类型可能公开不可序列化的函数(如果不是 getter,或者 getter 带有参数)。 我建议你把你想要的所有数据调用并存储到单独的键中,稍后重新读取它们。
Cache.setItem("CognitoUser", result);
Cache.setItem("CognitoUser-value-1", result.myFunction1("myArg1"));
Cache.setItem("CognitoUser-value-2", result.myFunction2("myArg2"));
// ..
var user = Cache.getItem("CognitoUser");
var myVal1 = Cache.getItem("CognitoUser-value-1");
var myVal2 = Cache.getItem("CognitoUser-value-2");
如果您使所有上述函数都可序列化,您还可以在 localStorage 中保留一个键 "CognitoUser"
。例如,扩展 result
的类型,添加原型 getter 函数(无参数),每次调用和返回各自的 myFunctionX("myArgX")
函数,这样它们就会出现在 JSON.stringify进程。
我的工作,
所以这个问题困扰了我一段时间。 Amplify Cache 似乎不起作用,缓存用户名和密码是个坏主意,但是我的解决方法只是在 Require-New-Password 表单中包含用户名和密码,所以我有 4 个输入,而不仅仅是 newPassword 和 confirmPassword现在是用户名、旧密码、新密码和确认密码。
https://github.com/aws-amplify/amplify-js/issues/1715#issuecomment-642733574