我使用 AWS Amplify 通过电子邮件/密码和 Google 联合登录进行身份验证。我还利用 Hub
API 来侦听身份验证更改。当用户使用电子邮件/密码登录时,我们的用户将被重定向到私有路由,一切都按预期进行。当用户使用 Google 联合登录名登录时,页面重定向到 google,然后我的私有路由捕获此登录名并将其重定向回登录。
重定向到 google 进行登录后,Amplify 假设将我们发送回 /PrivateRoute
。
我尝试使用 <Route>
和 exact
调整我的 strict
属性,但问题仍然存在。
这是我使用身份验证处理私有路由的标准方式,但我第一次使用 Amplify 联合登录。有什么建议吗?
参见下面的示例代码:
aws-exports.js
...
cont awsConfig = {
...
oauth: {
...
redirectSignIn: "http://localhost:3000/PrivateRoute
redirectSignOut: "http://localhost:3000/SignIn
...
}
PrivateRoute.js
import React, { useContext } from "react";
import { Route, Redirect } from "react-router-dom";
import { AuthContext } from "../AuthContextProvider.js";
const PrivateRoute = (props) => {
const { component: Component, ...rest } = props;
const user = useContext(AuthContext);
console.log(user)
return (
<Route
{...rest}
render={(matchProps) =>
user ? <Component {...matchProps} /> : <Redirect to="/SignIn" />
}
/>
);
};
export default PrivateRoute;
AuthContextProvider.js
import React, { useState, useEffect } from "react";
import Amplify, { Auth, Hub } from "aws-amplify";
const AuthContext = React.createContext();
const AuthContextProvider = (props) => {
const [user, setUser] = useState(null);
useEffect(() => {
Amplify.configure(props.awsconfig);
Hub.listen("auth", ({ payload: { event, data } }) => {
switch (event) {
case "signIn":
setUser(data);
break;
case "signOut":
setUser(null);
break;
default:
break;
}
});
Auth.currentAuthenticatedUser()
.then((user) => setUser(user))
.catch((user) => setUser(null));
}, []);
return (
<AuthContext.Provider value={user}>{props.children}</AuthContext.Provider>
);
};
export default AuthContextProvider;
export { AuthContext };
SignIn.js
...
import { Auth } from "aws-amplify";
import { AuthContext } from "../AuthContextProvider.js";
...
const SignIn = ({ config }) => {
...
const user = useContext(AuthContext);
async function handleSignIn() {
try {
const user = await Auth.signIn(email, password);
if (user) {
history.push(redirectPath);
}
} catch (error) {
console.log("error signing in:", error);
}
}
if (user) {
return <Redirect to={redirectPath} />;
}
return (
<Button onClick={() => handleSignIn()}
Email/PW Log In
</Button>
<Button onClick={() => Auth.federatedSignIn({ provider: "Google" })}
Google Log In
</Button>
);
};
答案 0 :(得分:0)
这个解决方案的答案现在显而易见。
在我的 AuthContextProvider.js 中,我需要在加载依赖组件之前等待我的异步授权。
通过添加以下状态:
const [isLoadingUser, setIsLoadingUser] = useState(true);
然后我可以设置:
Auth.currentAuthenticatedUser()
.then((user) => {
setUser(user)
setIsLoadingUser(false) // set bool upon completion
})
.catch((user) => {
setUser(null)
setIsLoadingUser(false) // set bool upon failure
});
}, []);
最后,如果我的整个应用程序都在身份验证之后,我可以改为返回一个加载组件:
if (isLoadingUser) {
return (<LoadingUser />)
}