使用私有路由和上下文响应身份验证
Posted
技术标签:
【中文标题】使用私有路由和上下文响应身份验证【英文标题】:React authentication with private routes and context 【发布时间】:2020-02-22 01:28:53 【问题描述】:我正在尝试使用私有路由和上下文向 React+Typescript 应用程序添加简单的身份验证。我有一个简单的登录组件,它带有一个按钮,它只是将上下文中的布尔变量authenticated
设置为true。私有路由应该检查这个 var 并重定向到登录组件,如果它不是真的,否则显示指定的组件。问题是authenticated
似乎总是错误的,我总是被重定向到登录页面。
当我调试它时,我可以看到 AuthContextProvider 中的setAuthenticated
函数在单击登录按钮时被调用。但是,如果我随后单击任何指向私有路由的链接,authenticated
总是错误的。
这是我的 App.tsx:
function App()
return (
<AuthContextProvider>
<Router>
<Link to="/">Home</Link>
<Link to="/projects">Projects</Link>
<div>
<Route path="/login" component=Login />
<PrivateRoute path="/" exact component=Home />
<PrivateRoute path="/projects" component=Projects />
</div>
</Router>
</AuthContextProvider>
);
export default App;
PrivateRoute.tsx:
interface PrivateRouteProps extends RouteProps
// tslint:disable-next-line:no-any
component: any;
const PrivateRoute = (props: PrivateRouteProps) =>
const component: Component, ...rest = props;
return (
<AuthContextConsumer>
authContext => authContext && (
<Route ...rest
render= props =>
authContext.authenticated === true ? (
<Component ...props />
) : (
<Redirect to="/login" />
)
/>
)
</AuthContextConsumer>
);
;
export default PrivateRoute;
AuthContext.tsx:
export interface AuthContextInterface
authenticated: boolean,
setAuthenticated(newAuthState: boolean):void
const ctxt = React.createContext<AuthContextInterface>(
authenticated: false,
setAuthenticated: () =>
);
export class AuthContextProvider extends React.Component
setAuthenticated = (newAuthState:boolean) =>
this.setState( authenticated: newAuthState );
;
state =
authenticated: false,
setAuthenticated: this.setAuthenticated,
;
render()
return (
<ctxt.Provider value=this.state>
this.props.children
</ctxt.Provider>
);
export const AuthContextConsumer = ctxt.Consumer;
登录.tsx:
function Login()
return (
<AuthContextConsumer>
( authenticated, setAuthenticated ) => (
<div>
<p>Login</p>
<form>
<input type="text" placeholder="Username"/>
<input type="password" placeholder="Password"/>
<button onClick=event =>
setAuthenticated(true);
>Login</button>
</form>
</div>
)
</AuthContextConsumer>
);
export default Login;
我怀疑 AuthContextProvider 中的状态定义有问题。如果我在这里将authenticated
in 更改为 true,我会看到相反的行为,我永远不会看到登录页面。这应该是动态的吗?
【问题讨论】:
【参考方案1】:或者,在 onClick 回调中,设置 event.preventDefault()
使其不提交表单。
【讨论】:
【参考方案2】:问题原来是每次按下登录按钮时应用都在重新加载,因此丢失了 AuthContext 中的状态。
原因是在我的登录组件中,我在表单中有一个按钮,它会自动提交表单并重新加载页面。
解决办法是要么去掉表单标签,要么在按钮中指定属性type="button"
。
【讨论】:
以上是关于使用私有路由和上下文响应身份验证的主要内容,如果未能解决你的问题,请参考以下文章
从cookie异步加载身份验证令牌时,React react-router-dom私有路由不起作用
如何响应最近的私有 API 更改执行未经身份验证的 Instagram 网络抓取?