为基本身份验证反应私有路由

时间:2021-05-16 14:42:01

标签: javascript reactjs react-hooks fetch basic-authentication

我正在尝试在我的 React 应用程序中实现基本身份验证。在向我的 nextView 端点发出 email 请求时,我在标头中发送了 passwordGET,并根据响应决定登录是否成功。如果登录成功(即用户存在于端点),那么我们推送到 /users 组件。但我希望用户只有在他是有效用户时才能访问 <projects> 网址。我如何申请私人路线

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

/projects

这是发送正确凭据 (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 对象的外观

email: abc, password: test

我的回复是这样的

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

App.js

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

1 个答案:

答案 0 :(得分:1)

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

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

// 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")。