Javascript 如何在react路由器中限制对路由的访问?
有人知道如何限制对react路由器中特定路由的访问吗?在允许访问特定路由之前,我想检查用户是否已登录。我以为这会很简单,但医生们不清楚怎么做 这是我应该在定义Javascript 如何在react路由器中限制对路由的访问?,javascript,reactjs,react-router,Javascript,Reactjs,React Router,有人知道如何限制对react路由器中特定路由的访问吗?在允许访问特定路由之前,我想检查用户是否已登录。我以为这会很简单,但医生们不清楚怎么做 这是我应该在定义组件的地方设置的,还是应该在组件处理程序中处理 <Route handler={App} path="/"> <NotFoundRoute handler={NotFound} name="not-found"/> <DefaultRoute handler={Login} name="login"/&
组件的地方设置的,还是应该在组件处理程序中处理
<Route handler={App} path="/">
<NotFoundRoute handler={NotFound} name="not-found"/>
<DefaultRoute handler={Login} name="login"/>
<Route handler={Todos} name="todos"/> {/* I want this to be restricted */}
</Route>
{/*我想限制它*/}
通常,登录用户将被授予令牌,并将该令牌用于与服务器的任何通信。我们通常做的是定义一个根页面,然后在该页面上构建内容。此根页面为您执行本地化、身份验证和其他配置
这里有一个例子
Routes = (
<Route path="/" handler={Root}>
<Route name="login" handler={Login} />
<Route name="forget" handler={ForgetPassword} />
<Route handler={Main} >
<Route name="overview" handler={Overview} />
<Route name="profile" handler={Profile} />
<DefaultRoute handler={Overview} />
</Route>
<DefaultRoute handler={Login} />
<NotFoundRoute handler={NotFound} />
</Route>
);
Routes=(
);
在您的根页面上,检查令牌null或向服务器验证令牌,以查看用户是否有效登录
希望这有帮助:)如果您想在整个应用程序中使用身份验证,您需要在应用程序范围内存储一些数据(例如令牌)。您可以设置两个React mixin,它们负责管理
$auth
对象。这个对象不应该在这两个mixin之外可用。下面是一个例子:
define('userManagement', function() {
'use strict';
var $auth = {
isLoggedIn: function () {
// return something, e.g. using server-stored data
}
};
return {
Authenticator: {
login: function(username, password) {
// modify $auth object, or call server, or both
}
},
NeedsAuthenticatedUser: {
statics: {
willTransitionTo: function (transition) {
if (!$auth.isLoggedIn()) {
transition.abort();
}
}
}
}
};
});
然后,您可以将Authenticator
混合到您的登录组件(登录屏幕、登录弹出窗口等)中,并在获得所有必要数据后调用this.login
函数
最重要的是通过混合NeedsAuthenticatedUser
mixin来保护组件。每个需要经过身份验证的用户的组件必须如下所示:
var um = require('userManagement');
var ProtectedComponent = React.createClass({
mixins: [um.NeedsAuthenticatedUser]
// ...
}
请注意,NeedsAuthenticatedUser
使用react路由器API(willtransitionon
和transition.abort()
)。更新(2019年8月16日)
在react router v4和使用react挂钩时,这看起来有点不同。让我们从你的App.js
开始
导出默认函数App(){
const[isAuthenticated,userHasAuthenticated]=useState(false);
useffect(()=>{
onLoad();
}, []);
异步函数onLoad(){
试一试{
等待Auth.currentSession();
userHasAuthenticated(true);
}捕获(e){
警报(e);
}
}
返回(
欢迎使用我的应用程序
旧版本
公认的答案是正确的,但React团队认为混入有害()
如果有人遇到这个问题,并且正在寻找推荐的方法,我建议使用高阶组件而不是mixin
下面是一个HOC示例,它将在继续操作之前检查用户是否登录。如果用户未登录,则它将重定向到登录页面。此组件采用一个名为isLoggedIn
的道具,它基本上是应用程序可以存储的一个标志,用于指示用户是否登录
从“React”导入React;
从“react router”导入{withRouter};
导出默认函数requireAuth(组件){
类AuthenticatedComponent扩展了React.Component{
组件willmount(){
this.checkAuth();
}
checkAuth(){
如果(!this.props.isLoggedIn){
const location=this.props.location;
const redirect=location.pathname+location.search;
this.props.router.push(`/login?redirect=${redirect}`);
}
}
render(){
返回此.props.isLoggedIn
?
:null;
}
}
返回路由器(认证组件);
}
要使用这个HOC,只需将它环绕在您的路线上。对于您的示例,它将是:
<Route handler={requireAuth(Todos)} name="todos"/>
我在一个详细的分步教程中介绍了这一点和其他一些主题-react router
鼓励对路由器采用声明式方法,您应该使路由器尽可能哑,并避免将路由逻辑放入组件中
下面是您可以执行此操作的方法(假设您将loggedIn
prop传递给它):
const DumbRouter=({loggedIn})=>(
{[
!loggedIn&&loggedoutrotes,
loggedIn&&LoggedInRouter,
]}
);
常数LoggedInRoutes=[
];
常数对数对数=[
];
在React Router 4的文档中(现在?)有一个这样的例子
从'react router'导入{Route,Redirect}
(
洛格丁(
) : (
)
)}/>
private-route.tsx
从'react router'导入{Redirect,Route,RouteProps};
从“React”导入*作为React;
接口PrivateRouteProps扩展了RouteProps{
/**
*例如“/login”。
*/
重定向到:字符串;
/**
*如果为true,则不会重定向。
*我们使用的是函数而不是bool,bool似乎没有更新
*在成功认证之后。
*/
isLogged:()=>布尔值;
}
导出函数PrivateRoute(道具:PrivateRoutes道具){
//`component:component`未键入,它将值分配给新变量。
让{isloged,redirectTo,component:component,…rest}:any=props;
//错误:JSX类型元素组件没有调用签名或…通过添加任何仍在工作的,
//没有找到一个合适的方法来修复它。
返回(
isLogged()
?
:
)} />;
}
用法:
<PrivateRoute exact={true}
path="/admin/"
redirectTo={'/admin/login'}
isLogged={this.loginService.isLogged}
component={AdminDashboardPage}/>
<Route path="/admin/login/" component={AdminLoginPage}/>
基于。您可以使用HOC,auth是一个变量,您可以更改值true或false表示(授权)
(auth?():())}/>
您可以避免在确认身份验证之前呈现组件,如下所示:
import { useState, useEffect, useRef } from 'react';
import { useHistory } from 'react-router-dom';
const Route = () => {
const [loading, sertLoading] = useState(true);
const history = useHistory();
const ref = useRef<Function>({});
// must use ref!
ref.current.routeGuard = () => {
const authenticationHandler = (): boolean => {
// do authentication here
}
sertLoading(true);
const go = authenticationHandler();
if (go === false) {
history.goBack();
}
sertLoading(false);
}
useEffect(() => {
ref.current.routeGuard();
history.listen(() => {
ref.current.routeGuard();
});
}, []);
return (
<>
{!loading && <YourRouteComponent />}
</>
)
};
从'react'导入{useState,useffect,useRef};
从'react router dom'导入{useHistory};
常数路由=()=>{
const[loading,sertLoading]=使用状态(true);
const history=useHistory();
const ref=useRef({});
//必须使用ref!
ref.current.routeGuard=()=>{
有限公司
import {Redirect, Route, RouteProps} from 'react-router';
import * as React from 'react';
interface PrivateRouteProps extends RouteProps {
/**
* '/login' for example.
*/
redirectTo: string;
/**
* If true, won't redirect.
* We are using a function instead of a bool, a bool does not seem to be updated
* after having successfully authenticated.
*/
isLogged: () => boolean;
}
export function PrivateRoute(props: PrivateRouteProps) {
// `component: Component` is not typing, it assign the value to a new variable.
let { isLogged, redirectTo, component: Component, ...rest }: any = props;
// error: JSX type element Component does not have call signature or ... AVOIDED BY ADDING ANY, still work,
// and did not find a proper way to fix it.
return <Route {...rest} render={(props) => (
isLogged()
? <Component {...props}/>
: <Redirect to={{
pathname: redirectTo,
state: { from: props.location }
}} />
)} />;
}
<PrivateRoute exact={true}
path="/admin/"
redirectTo={'/admin/login'}
isLogged={this.loginService.isLogged}
component={AdminDashboardPage}/>
<Route path="/admin/login/" component={AdminLoginPage}/>
<Route path="/login" component={SignIn} />
<Route path="/posts" render = {() => (auth ? (<Post />) : (<Redirect to="/login" />))}/>
import { useState, useEffect, useRef } from 'react';
import { useHistory } from 'react-router-dom';
const Route = () => {
const [loading, sertLoading] = useState(true);
const history = useHistory();
const ref = useRef<Function>({});
// must use ref!
ref.current.routeGuard = () => {
const authenticationHandler = (): boolean => {
// do authentication here
}
sertLoading(true);
const go = authenticationHandler();
if (go === false) {
history.goBack();
}
sertLoading(false);
}
useEffect(() => {
ref.current.routeGuard();
history.listen(() => {
ref.current.routeGuard();
});
}, []);
return (
<>
{!loading && <YourRouteComponent />}
</>
)
};