反应私有路由以进行基本身份验证

React private routes for basic authentication

我正在尝试在我的 React 应用程序中实施基本身份验证。在向我的 /users 端点发出 GET 请求时,我在 header 中发送了 emailpassword,根据响应我们决定登录是否是成功与否。如果登录成功(即用户存在于端点),那么我们将推送到 <projects> 组件。但是我希望用户只有在他是有效用户的情况下才能访问 /projects url。如何申请私有路由

这是我的登录页面代码的样子 函数登录(){

const [password, setPassword] = React.useState("");
const [email, setEmail] = React.useState("");
const [err, setErr] = React.useState(null);

const history = useHistory();

const handleSubmit = async (event, password, email) => {
    event.preventDefault();

    var myHeaders = new Headers();
    myHeaders.set('Authorization', 'Basic ' + encode(email + ":" + password));

    var requestOptions = {
    method: 'GET',
    headers: myHeaders,
    redirect: 'follow'
    };

    let response;

    try {
        response = await fetch (`${APIlink}/users`, requestOptions)
    } catch (err) {
        setErr("Incorrect Password. Please Retry.");
        return;
    }

    const result = await response.text();
    console.log(result);
    const json = JSON.parse(result);
    console.log(json);
    console.log(response);
    

    if (response.status===200) {
        setErr(null);
        history.push("/Projects"); //valid user is redirected but /Projects is accessible by just
                                   //writing the url as well
        } else {
        setErr(json.error);
        console.log(json.error);
        }
    };

这就是我的 json object 在发送正确的凭据后的样子 (email: abc, password: test)

{
  "password": "test",
  "rollno": "18am200",
  "email": "abc",
  "name": "mkyong",
  "user-uid": "7e7199247de1125a6dc1518dd78ba554"
}

我的回复是这样的

Response { type: "cors", url: "{APIlink/users", redirected: false, status: 200, ok: true, statusText: "OK", headers: Headers, body: ReadableStream, bodyUsed: true }

App.js

function App() {
    return (
      <div >
        <HashRouter basename ='/'>
        <Switch>
          <Route path="/" component = {Home} exact/>
          <Route path="/Login" component = {LogIn}/>
          <Route path="/Register" component = {Register}/>
          <Route path="/Projects" component = {ProjectComponent} />
          <Route path="/Application" component = {Project2Component} />
          <Route path="/Demo1" component = {Project3Component} />  
          <Route path="/Demo2" component = {Project4Component} />     
        </Switch>
        </HashRouter>
    </div>
    )
  }

export default App

您可以在成功响应登录后为您的 LocalStorage 设置一个持久值(例如 isAuthenticated = true)。但请确保在用户注销后删除该值(例如 isAuthenticated = false)。然后您可以在每次用户更改 his/her route.

时检查该值

我在下面为您添加了一些基本示例 -

// Login.js

/* other codes ... */
if (response.status===200) {
    localStorage.setItem('isAuthenticated', true);
    history.push("/Projects");
};
/* other codes ... */
// Logout.js

localStorage.removeItem('isAuthenticated');
// AuthRequired.js

import React, { Fragment } from "react"
import { Redirect } from "react-router-dom"

export default function AuthRequired(props){
    const isAuthenticated = localStorage.getItem('isAuthenticated')

    if(isAuthenticated){
        return props.orComponent;
    } else {
        return <Redirect to="/Login"/>
    }
}
// App.js

import { Route, Switch } from "react-router-dom"
import AuthRequired from "./AuthRequired"

/* Your other codes and imports.. */

const publicRoutes = [
    {
        path: "/Login",
        exact: true,
        component: LogIn
    },
    {
        path: "/",
        exact: true,
        component: Home
    },
];

const authRequiredRoutes = [
    {
        path: "/Projects",
        exact: true,
        component: <ProjectComponent/>
    },
    // ... other routes
]

const pathsForLayout = routes => routes.map(route => route.path)

function App() {
    return (
        <div >
            <HashRouter basename ='/'>
                <Switch>
                    <Route exact path={pathsForLayout(publicRoutes)}>
                        <Switch>
                            {
                                publicRoutes.map((route,index) => (
                                    <Route
                                        key={index}
                                        exact={route.exact}
                                        path={route.path}
                                        component={route.component}
                                    />
                                ))
                            }
                        </Switch>
                    </Route>
                    <Route exact path={pathsForLayout(authRequiredRoutes)}>
                        <Switch>
                            {
                                authRequiredRoutes.map((route,index) => (
                                    <Route
                                        key={index}
                                        exact={route.exact}
                                        path={route.path}
                                        render={() => (
                                             <AuthRequired 
                                                 {...props}
                                                 orComponent={route.component}
                                             />
                                        )}
                                    />
                                ))
                            }
                        </Switch>
                    </Route>
                    <Route component={NotFound} /> {/* Your custom 404 page */}
               </Switch>
           </HashRouter>
        </div>
    )
}

export default App

注意-我遵循了你的路线命名约定。这就是为什么我也将它们保留为 PascalCase。尽管声明 path of <Route/> 的推荐方法是使用 kebab-case。 (例如 path="/login")。