使用API​​调用验证问题来响应路由器专用路由

时间:2020-08-02 17:16:20

标签: node.js reactjs react-native

我正在尝试创建专用路由并验证登录名,我想执行API调用,它需要异步处理,但是不能在专用路由组件内使用异步处理。因此尝试使用useEffect(),但它也显示了自身的局限性,存在以下问题:

  1. 未验证会话时,它将显示“登录”页面,但保持URL不变。
  2. 用户已经登录并尝试访问“登录”页面时,它永远不会自动登录。

我的简单要求是拥有两条路由,分别是“公共”和“私有”,并验证用户是否登录。它需要执行API调用以检查用户是否具有有效的会话。

如果我能在React中学习,那么任何人都可以纠正我的代码或指导如何修复它会很有帮助。提前谢谢。

以下是我的代码: Router.js

if rv is None:

verifyToken.js

import React, {Suspense, lazy, useEffect, useState  } from "react"
import { Router, Switch, Route, Redirect } from "react-router-dom"
import { history } from "./history"
import { connect } from "react-redux"
import Spinner from "./components/@project/spinner/Loading-spinner"
import { ContextLayout } from "./utility/context/Layout"
import verifyToken from './authServices/verifyToken'


// Route-based code splitting
const dashboard = lazy(() => import("./views/Dashboards/Dashboard"))
const profile = lazy(() => import("./views/Profile"))

//error Pages
const error404 = lazy(() => import("./views/Misc/error/404"))
const error500 = lazy(() => import("./views/Misc/error/500"))
const authorized = lazy(() => import("./views/Misc/NotAuthorized"))
const maintenance = lazy(() => import("./views/Misc/Maintenance"))
//AuthorizedPages
const Login = lazy(() => import("./views/authentication/login/Login"))
const forgotPassword = lazy(() => import("./views/authentication/ForgotPassword"))
const lockScreen = lazy(() => import("./views/authentication/LockScreen"))
const register = lazy(() => import("./views/authentication/register/Register"))

// Set Layout and Component Using App Route

function useVerified(auth, path){
  const [verified, setVerifiedValue] = useState();
  useEffect(() => {
    const doVerify = async () => {
      setVerifiedValue(await verifyToken(auth))
    }
    doVerify()
  }, [path])
  return verified;
}

const RouteConfig =  ({ component: Component, fullLayout, user, auth, ...rest}) => {
 const path = ({...rest}.path)
 const verified = useVerified(auth, path);
  return <Route
    {...rest} 
    render={props => {
      return (
        <ContextLayout.Consumer>
          {context => {
            let LayoutTag =
              fullLayout === true
                ? context.fullLayout
                : context.VerticalLayout
            
            return  (auth.values !== undefined && auth.values.isSignedIn && verified) ? (
              <LayoutTag {...props} permission={user}>
                <Suspense fallback={<Spinner />}>
                  <Component {...props}></Component>
                </Suspense>
              </LayoutTag>
            ) : (
              <context.fullLayout {...props} permission={user}>
                <Suspense fallback={<Spinner />}>
                  <Login {...props} />
                </Suspense>
              </context.fullLayout>
            )
          }}
        </ContextLayout.Consumer>
      )
    }}
  />
}
const mapStateToProps = state => {
  return {
    user: state.auth.login.userRole,
    auth: state.auth.login
  }
}

const AppRoute = connect(mapStateToProps)(RouteConfig)


const PublicRoute = ({ component: Component, fullLayout, ...rest }) => (
  <Route {...rest} render={() => {
      return (
        <ContextLayout.Consumer>
          {context => {
            let LayoutTag =
              fullLayout === true
                ? context.fullLayout
                : context.VerticalLayout
            return (
              <LayoutTag>
                <Suspense fallback={<Spinner />}>
                  <Component/>
                </Suspense>
              </LayoutTag>
            )
          }}
        </ContextLayout.Consumer>
      )
    }}
  />
)

class AppRouter extends React.Component {
  render() {
    return (
      // Set the directory path if you are deploying in sub-folder
      <Router history={history}>
        <Switch>
          <PublicRoute exact path="/login" component={Login} fullLayout />
          <PublicRoute exact path="/" component={Login} fullLayout />
          <PublicRoute path="/register" component={register} fullLayout />
          <PublicRoute path="/forgot-password"  component={forgotPassword} fullLayout />

          <AppRoute path="/dashboard" component={dashboard} />
          <AppRoute path="/profile" component={profile} />
          
          <AppRoute path="/404" component={error404} fullLayout />
          <AppRoute path="/500" component={error500} fullLayout />
          <AppRoute path="/not-authorized" component={authorized} fullLayout />
          <AppRoute path="/maintenance" component={maintenance} fullLayout />
     
          <AppRoute component={error404} fullLayout />
        </Switch>
      </Router>
    )
  }
}

export default AppRouter

API呼叫代码

import jwt from 'jsonwebtoken';
import { refreshToken } from "../redux/actions/auth/loginActions"

const verifyToken = async props => {
    if('accessToken' in props && 'accessToken' in props.accessToken){
        if (props.accessToken.accessToken !== undefined && props.accessToken.accessToken !== null) {
            if (assertAlive(jwt.decode(props.accessToken.accessToken))) {
                const verified = await refreshToken(props)
                if (verified){
                    return true
                } else {
                    return false
                }
            } else {
                return false
            }
        }else 
            return false
    }else
        return false
}

function assertAlive (decoded) {
    const now = Date.now().valueOf() / 1000
    if (typeof decoded.exp !== 'undefined' && decoded.exp < now) {
      //throw new Error(`token expired: ${JSON.stringify(decoded)}`)
      return false
    }
    if (typeof decoded.nbf !== 'undefined' && decoded.nbf > now) {
      //throw new Error(`token not yet valid: ${JSON.stringify(decoded)}`)
      return false
    }
    return true
  }

export default verifyToken;

0 个答案:

没有答案