रिएक्ट राउटर 4 में प्रमाणित मार्गों को कैसे लागू किया जाए?


122

मैं प्रमाणित मार्गों को लागू करने की कोशिश कर रहा था, लेकिन पाया कि रिएक्ट राउटर 4 अब इसे काम करने से रोकता है:

<Route exact path="/" component={Index} />
<Route path="/auth" component={UnauthenticatedWrapper}>
    <Route path="/auth/login" component={LoginBotBot} />
</Route>
<Route path="/domains" component={AuthenticatedWrapper}>
    <Route exact path="/domains" component={DomainsIndex} />
</Route>

त्रुटि है:

चेतावनी: यदि आप उपयोग नहीं करना चाहिए <Route component>और <Route children>एक ही मार्ग में; <Route children>नजरअंदाज कर दिया जाएगा

उस मामले में, इसे लागू करने का सही तरीका क्या है?

यह react-router(v4) डॉक्स में प्रकट होता है , यह कुछ ऐसा सुझाता है

<Router>
    <div>
    <AuthButton/>
    <ul>
        <li><Link to="/public">Public Page</Link></li>
        <li><Link to="/protected">Protected Page</Link></li>
    </ul>
    <Route path="/public" component={Public}/>
    <Route path="/login" component={Login}/>
    <PrivateRoute path="/protected" component={Protected}/>
    </div>
</Router>

लेकिन क्या एक साथ मार्गों का एक समूह बनाते समय इसे प्राप्त करना संभव है?


अपडेट करें

ठीक है, कुछ शोध के बाद, मैं इसके साथ आया:

import React, {PropTypes} from "react"
import {Route} from "react-router-dom"

export default class AuthenticatedRoute extends React.Component {
  render() {
    if (!this.props.isLoggedIn) {
      this.props.redirectToLogin()
      return null
    }
    return <Route {...this.props} />
  }
}

AuthenticatedRoute.propTypes = {
  isLoggedIn: PropTypes.bool.isRequired,
  component: PropTypes.element,
  redirectToLogin: PropTypes.func.isRequired
}

render()इसमें गलत तरीके से कार्रवाई करना सही है। यह वास्तव में componentDidMountया कुछ अन्य हुक के साथ सही नहीं लगता है ?


अगर सर्वर साइड रेंडरिंग का उपयोग नहीं कर रहा है तो इटैलियनवेटमाउंट पर सबसे अच्छा।
म्हादी

@ मफहदी, इनपुट के लिए धन्यवाद। मैं अभी तक SSR का उपयोग नहीं कर रहा हूं, लेकिन अगर मैं भविष्य में उपयोग करना चाहता हूं, तो क्या मैं इसे रेंडर में रखता हूं? यदि उपयोगकर्ता को पुनर्निर्देशित किया जाता है componentWillMount, तो क्या उन्हें विभाजित दूसरे के लिए भी प्रस्तुत आउटपुट देखने को मिलेगा?
Jiew मेंग

मुझे यह कहने के लिए वास्तव में खेद है कि componentWillMount()एसएसआर पर नहीं बुलाया गया है, यह है componentDidMount()कि नहीं कहा जाता है। जैसा componentWillMount()कि पहले कहा जाता है render(), इसलिए उपयोगकर्ता को नए घटक का कुछ भी दिखाई नहीं देगा। तो यह जाँच करने के लिए सबसे अच्छी जगह है।
म्हादी

1
आप डिस्पैच कार्रवाई को कॉल करने के बजाय <Redirect to="/auth"> डॉक्स से बस का उपयोग कर सकते हैं
फ्यूजेल लॉर्डऑर्डर

जवाबों:


239

आप Redirectघटक का उपयोग करना चाहते हैं। इस समस्या के लिए कुछ अलग तरीके हैं। यहाँ एक मुझे पसंद है, एक PrivateRoute घटक है जो एक authedप्रोप में लेता है और फिर उस सहारा के आधार पर रेंडर करता है।

function PrivateRoute ({component: Component, authed, ...rest}) {
  return (
    <Route
      {...rest}
      render={(props) => authed === true
        ? <Component {...props} />
        : <Redirect to={{pathname: '/login', state: {from: props.location}}} />}
    />
  )
}

अब आपका Routeकुछ इस तरह दिख सकता है

<Route path='/' exact component={Home} />
<Route path='/login' component={Login} />
<Route path='/register' component={Register} />
<PrivateRoute authed={this.state.authed} path='/dashboard' component={Dashboard} />

यदि आप अभी भी भ्रमित हैं, तो मैंने इस पोस्ट को लिखा है जो मदद कर सकता है - रिएक्ट राउटर v4 के साथ संरक्षित मार्ग और प्रमाणीकरण


2
ओह, यह मेरे समाधान के समान है, लेकिन इसका उपयोग करता है <Redirect />। समस्या <Redirect />मेरे मामले में redux के साथ काम करने की नहीं लगती है? मुझे एक एक्शन भेजने की जरूरत है
Jiew मेंग

3
मुझे पता नहीं क्यों, लेकिन जोड़ने के state: {from: props.location}}}कारण एक maximum call stack exceeded। मुझे इसे हटाना पड़ा। क्या आप बता सकते हैं कि यह विकल्प उपयोगी क्यों है @ टायलर मैकगिनिस?
मार्टीपी

@ कीटिज अजीब है। यह उपयोगी है क्योंकि यह आपको बताता है कि आप कहां से आए हैं। एक उदाहरण यह होगा कि यदि आप उपयोगकर्ता को प्रमाणित करना चाहते हैं, तो एक बार प्रमाणित करने के बाद, उन्हें उस पृष्ठ पर वापस ले जाएं, जिसे वे आपके रीडायरेक्ट होने से पहले एक्सेस करने का प्रयास कर रहे थे।
टायलर मैकगिनीस

6
@ फ़राज़ यह ({component: Component, ...rest})वाक्य रचना की व्याख्या करता है। मेरे पास वही सवाल था! stackoverflow.com/a/43484565/6502003
protoEvangelion

2
@TylerMcGinnis घटक को प्रॉपर पास करने के लिए हमें रेंडर फ़ंक्शन का उपयोग करने की आवश्यकता है तो क्या होगा?
सी बाउर

16

समाधान के लिए Tnx टायलर मैकगिनिस। मैं अपना विचार टायलर मैकगिनिस के विचार से बनाता हूं।

const DecisionRoute = ({ trueComponent, falseComponent, decisionFunc, ...rest }) => {
  return (
    <Route
      {...rest}

      render={
        decisionFunc()
          ? trueComponent
          : falseComponent
      }
    />
  )
}

आप इसे इस तरह लागू कर सकते हैं

<DecisionRoute path="/signin" exact={true}
            trueComponent={redirectStart}
            falseComponent={SignInPage}
            decisionFunc={isAuth}
          />

निर्णय केवल एक ऐसा फ़ंक्शन है जो सही या गलत लौटाता है

const redirectStart = props => <Redirect to="/orders" />

8

(राज्य प्रबंधन के लिए Redux का उपयोग करना)

यदि उपयोगकर्ता किसी भी यूआरएल को एक्सेस करने का प्रयास करता है, तो सबसे पहले मैं यह जांचने जा रहा हूं कि क्या उपलब्ध टोकन उपलब्ध है, यदि लॉगिन पृष्ठ पर रीडायरेक्ट नहीं किया जाता है, एक बार लॉगिन पेज का उपयोग करने के बाद उपयोगकर्ता लॉग इन करता है, तो हम इसे स्थानीय स्टोर के साथ-साथ हमारे redux राज्य में संग्रहीत करते हैं। (स्थानीय दुकान या कुकीज़..हम इस विषय को अभी के लिए संदर्भ से बाहर रखते हैं)।
अद्यतन और निजीकरण के रूप में redux राज्य के बाद से रेंडर किया जाएगा। अब हमारे पास टोकन एक्सेस है इसलिए हम होम पेज पर रीडायरेक्ट करने वाले हैं।

डिकोड किए गए प्राधिकरण पेलोड डेटा के साथ-साथ Redux राज्य में संग्रहीत करें और इसे संदर्भ प्रतिक्रिया के लिए पास करें। (हमें संदर्भ का उपयोग करने की आवश्यकता नहीं है, लेकिन हमारे किसी भी नेस्टेड बच्चे के घटकों में प्राधिकरण तक पहुँचने के लिए इसे संदर्भ से एक्सेस करने के बजाय प्रत्येक बच्चे के घटक को फिर से जोड़ने में आसान बनाता है) ।।

वे सभी मार्ग जिन्हें विशेष भूमिकाओं की आवश्यकता नहीं है, उन्हें लॉगिन के बाद सीधे एक्सेस किया जा सकता है .. यदि इसे व्यवस्थापक की तरह भूमिका की आवश्यकता है (हमने एक संरक्षित मार्ग बनाया है जो जाँचता है कि क्या उसकी वांछित भूमिका थी यदि अनधिकृत घटक को पुनर्निर्देशित नहीं किया गया है)

इसी तरह आपके किसी भी कंपोनेंट में अगर आपको बटन या किसी चीज़ को रोल के आधार पर डिसेबल करना है।

बस आप इस तरह से कर सकते हैं

const authorization = useContext(AuthContext);
const [hasAdminRole] = checkAuth({authorization, roleType:"admin"});
const [hasLeadRole] = checkAuth({authorization, roleType:"lead"});
<Button disable={!hasAdminRole} />Admin can access</Button>
<Button disable={!hasLeadRole || !hasAdminRole} />admin or lead can access</Button>

तो क्या होगा अगर यूजर लोकलस्टोरेज में डमी टोकन डालने की कोशिश करे। जैसा कि हमारे पास एक्सेस टोकन है, हम होम कंपोनेंट को रीडायरेक्ट करेंगे। मेरा होम कंपोनेंट डेटा हड़पने के लिए रेस्ट कॉल करेगा, क्योंकि jwt टोकन डमी था, बाकी कॉल अनधिकृत उपयोगकर्ता को वापस कर देगा। इसलिए मैं लॉगआउट कहता हूं (जो स्थानीयस्टोर को साफ कर देगा और फिर से लॉगिन पेज पर रीडायरेक्ट करेगा)। अगर होम पेज में स्टैटिक डेटा है और कोई एपीआई कॉल नहीं कर रहा है (तो आपको बैकएंड में टोकन-वेरिफाइड एप कॉल करना चाहिए ताकि आप चेक कर सकें कि होम पेज लोड करने से पहले टोकन असली है या नहीं)

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Router, Route, Switch } from 'react-router-dom';
import history from './utils/history';


import Store from './statemanagement/store/configureStore';
import Privateroutes from './Privateroutes';
import Logout from './components/auth/Logout';

ReactDOM.render(
  <Store>
    <Router history={history}>
      <Switch>
        <Route path="/logout" exact component={Logout} />
        <Route path="/" exact component={Privateroutes} />
        <Route path="/:someParam" component={Privateroutes} />
      </Switch>
    </Router>
  </Store>,
  document.querySelector('#root')
);

History.js

import { createBrowserHistory as history } from 'history';

export default history({});

Privateroutes.js

import React, { Fragment, useContext } from 'react';
import { Route, Switch, Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import { AuthContext, checkAuth } from './checkAuth';
import App from './components/App';
import Home from './components/home';
import Admin from './components/admin';
import Login from './components/auth/Login';
import Unauthorized from './components/Unauthorized ';
import Notfound from './components/404';

const ProtectedRoute = ({ component: Component, roleType, ...rest })=> { 
const authorization = useContext(AuthContext);
const [hasRequiredRole] = checkAuth({authorization, roleType});
return (
<Route
  {...rest}
  render={props => hasRequiredRole ? 
  <Component {...props} /> :
   <Unauthorized {...props} />  } 
/>)}; 

const Privateroutes = props => {
  const { accessToken, authorization } = props.authData;
  if (accessToken) {
    return (
      <Fragment>
       <AuthContext.Provider value={authorization}>
        <App>
          <Switch>
            <Route exact path="/" component={Home} />
            <Route path="/login" render={() => <Redirect to="/" />} />
            <Route exact path="/home" component={Home} />
            <ProtectedRoute
            exact
            path="/admin"
            component={Admin}
            roleType="admin"
          />
            <Route path="/404" component={Notfound} />
            <Route path="*" render={() => <Redirect to="/404" />} />
          </Switch>
        </App>
        </AuthContext.Provider>
      </Fragment>
    );
  } else {
    return (
      <Fragment>
        <Route exact path="/login" component={Login} />
        <Route exact path="*" render={() => <Redirect to="/login" />} />
      </Fragment>
    );
  }
};

// my user reducer sample
// const accessToken = localStorage.getItem('token')
//   ? JSON.parse(localStorage.getItem('token')).accessToken
//   : false;

// const initialState = {
//   accessToken: accessToken ? accessToken : null,
//   authorization: accessToken
//     ? jwtDecode(JSON.parse(localStorage.getItem('token')).accessToken)
//         .authorization
//     : null
// };

// export default function(state = initialState, action) {
// switch (action.type) {
// case actionTypes.FETCH_LOGIN_SUCCESS:
//   let token = {
//                  accessToken: action.payload.token
//               };
//   localStorage.setItem('token', JSON.stringify(token))
//   return {
//     ...state,
//     accessToken: action.payload.token,
//     authorization: jwtDecode(action.payload.token).authorization
//   };
//    default:
//         return state;
//    }
//    }

const mapStateToProps = state => {
  const { authData } = state.user;
  return {
    authData: authData
  };
};

export default connect(mapStateToProps)(Privateroutes);

checkAuth.js

import React from 'react';

export const AuthContext = React.createContext();

export const checkAuth = ({ authorization, roleType }) => {
  let hasRequiredRole = false;

  if (authorization.roles ) {
    let roles = authorization.roles.map(item =>
      item.toLowerCase()
    );

    hasRequiredRole = roles.includes(roleType);
  }

  return [hasRequiredRole];
};

JODT टोकेन समोसे की सजावट

{
  "authorization": {
    "roles": [
      "admin",
      "operator"
    ]
  },
  "exp": 1591733170,
  "user_id": 1,
  "orig_iat": 1591646770,
  "email": "hemanthvrm@stackoverflow",
  "username": "hemanthvrm"
}

और आप सीधे पहुंच कैसे संभालते हैं Signin? यदि कोई उपयोगकर्ता जानता है कि वह साइन इन नहीं है, तो उसके पास साइनइन को सीधे एक्सेस करने का विकल्प होना चाहिए, है ना?
कर्कोद

@ कर्कोड ... डिफ़ॉल्ट रूप से यदि वह किसी भी मार्ग का उपयोग करने का प्रयास करता है, तो उसे साइनइन पृष्ठ पर पुनर्निर्देशित किया जाएगा ... (क्योंकि वह टोकन नहीं
लेगा

@carkod .. एक बार उपयोगकर्ता लॉगआउट पर क्लिक करता है या फिर मेरा jwt ताज़ा टोकन समय सीमा समाप्त कर देता है .. मैं कॉल लॉगआउट फ़ंक्शन करता हूं, जहां मैं लोकलस्टोरेज और रिफ्रेश विंडो को साफ़ करता हूं ... इसलिए लोकलस्टोरन टोकन नहीं होगा..यह ऑटोमैटिक डेटा रीडायरेक्ट करेगा लॉग इन पेज पर
हेमंतव्र्म

मैं redux का उपयोग करने वालों के लिए इसका एक बेहतर संस्करण है..जिससे मैं कुछ ही दिनों में अपना उत्तर अपडेट कर सकूँ..धन्यवाद -
हेमंतव्र्म

3

प्रतिक्रिया-राउटर-डोम स्थापित करें

फिर वैध उपयोगकर्ताओं के लिए दो घटक बनाएं और अन्य अमान्य उपयोगकर्ताओं के लिए।

app.js पर यह कोशिश करो

import React from 'react';

import {
BrowserRouter as Router,
Route,
Link,
Switch,
Redirect
} from 'react-router-dom';

import ValidUser from "./pages/validUser/validUser";
import InValidUser from "./pages/invalidUser/invalidUser";
const loggedin = false;

class App extends React.Component {
 render() {
    return ( 
      <Router>
      <div>
        <Route exact path="/" render={() =>(
          loggedin ? ( <Route  component={ValidUser} />)
          : (<Route component={InValidUser} />)
        )} />

        </div>
      </Router>
    )
  }
}
export default App;

4
प्रति मार्ग? यह पैमाना नहीं होगा।
जिम जी।

3

@ टायलर मैकगिनिस के जवाब के आधार पर । मैं लिपटे घटकों के साथ ES6 सिंटैक्स और नेस्टेड मार्गों का उपयोग करके एक अलग दृष्टिकोण बनाता हूं :

import React, { cloneElement, Children } from 'react'
import { Route, Redirect } from 'react-router-dom'

const PrivateRoute = ({ children, authed, ...rest }) =>
  <Route
    {...rest}
    render={(props) => authed ?
      <div>
        {Children.map(children, child => cloneElement(child, { ...child.props }))}
      </div>
      :
      <Redirect to={{ pathname: '/', state: { from: props.location } }} />}
  />

export default PrivateRoute

और इसका उपयोग कर रहे हैं:

<BrowserRouter>
  <div>
    <PrivateRoute path='/home' authed={auth}>
      <Navigation>
        <Route component={Home} path="/home" />
      </Navigation>
    </PrivateRoute>

    <Route exact path='/' component={PublicHomePage} />
  </div>
</BrowserRouter>

2

मुझे पता है कि यह एक समय हो गया है, लेकिन मैं निजी और सार्वजनिक मार्गों के लिए एक npm पैकेज पर काम कर रहा हूं ।

यहाँ एक निजी मार्ग बनाने का तरीका बताया गया है:

<PrivateRoute exact path="/private" authed={true} redirectTo="/login" component={Title} text="This is a private route"/>

और आप ऐसे सार्वजनिक मार्ग भी बना सकते हैं, जिन पर केवल बिना उपयोग किए उपयोगकर्ता ही पहुंच सकते हैं

<PublicRoute exact path="/public" authed={false} redirectTo="/admin" component={Title} text="This route is for unauthed users"/>

मुझे उम्मीद है यह मदद करेगा!


क्या आप कृपया सभी आयात और रैप सहित अन्य उदाहरण प्रदान कर सकते हैं, उदाहरण के लिए 2 सार्वजनिक मार्गों, 2 निजी मार्गों और 2 PropsRoute में, मुख्य App.js में? धन्यवाद
एमएच

2

मैंने प्रयोग करके लागू किया-

<Route path='/dashboard' render={() => (
    this.state.user.isLoggedIn ? 
    (<Dashboard authenticate={this.authenticate} user={this.state.user} />) : 
    (<Redirect to="/login" />)
)} />

प्रमाणीकृत प्रॉप्स को उन घटकों को पास किया जाएगा जैसे साइनअप का उपयोग करके उपयोगकर्ता स्थिति को बदला जा सकता है। पूरा करें आवेदन-

import React from 'react';
import { Switch, Route } from 'react-router-dom';
import { Redirect } from 'react-router';

import Home from '../pages/home';
import Login from '../pages/login';
import Signup from '../pages/signup';
import Dashboard from '../pages/dashboard';

import { config } from '../utils/Config';

export default class AppRoutes extends React.Component {

    constructor(props) {
        super(props);

        // initially assuming that user is logged out
        let user = {
            isLoggedIn: false
        }

        // if user is logged in, his details can be found from local storage
        try {
            let userJsonString = localStorage.getItem(config.localStorageKey);
            if (userJsonString) {
                user = JSON.parse(userJsonString);
            }
        } catch (exception) {
        }

        // updating the state
        this.state = {
            user: user
        };

        this.authenticate = this.authenticate.bind(this);
    }

    // this function is called on login/logout
    authenticate(user) {
        this.setState({
            user: user
        });

        // updating user's details
        localStorage.setItem(config.localStorageKey, JSON.stringify(user));
    }

    render() {
        return (
            <Switch>
                <Route exact path='/' component={Home} />
                <Route exact path='/login' render={() => <Login authenticate={this.authenticate} />} />
                <Route exact path='/signup' render={() => <Signup authenticate={this.authenticate} />} />
                <Route path='/dashboard' render={() => (
                    this.state.user.isLoggedIn ? 
                            (<Dashboard authenticate={this.authenticate} user={this.state.user} />) : 
                            (<Redirect to="/login" />)
                )} />
            </Switch>
        );
    }
} 

पूरा प्रोजेक्ट यहां देखें: https://github.com/varunon9/hello-react


1

ऐसा लगता है कि आपकी हिचकिचाहट अपने स्वयं के घटक बनाने और फिर रेंडर विधि में भेजने की है? वैसे आप घटक की renderविधि का उपयोग करके दोनों से बच सकते <Route>हैं। <AuthenticatedRoute>जब तक आप वास्तव में नहीं चाहते तब तक एक घटक बनाने की आवश्यकता नहीं है। यह नीचे के रूप में सरल हो सकता है। {...routeProps}प्रसार को ध्यान में रखते हुए सुनिश्चित करें कि आप <Route>घटक के गुणों को बच्चे के घटक ( <MyComponent>इस मामले में) तक भेजना जारी रखते हैं ।

<Route path='/someprivatepath' render={routeProps => {

   if (!this.props.isLoggedIn) {
      this.props.redirectToLogin()
      return null
    }
    return <MyComponent {...routeProps} anotherProp={somevalue} />

} />

देखें प्रतिक्रिया रूटर V4 प्रलेखन प्रस्तुत करना

यदि आप एक समर्पित घटक बनाना चाहते हैं, तो ऐसा लगता है कि आप सही रास्ते पर हैं। चूंकि रिएक्ट राउटर V4 विशुद्ध रूप से घोषणात्मक रूटिंग है (यह विवरण में इतना सही कहता है) मुझे नहीं लगता कि आप सामान्य घटक जीवनचक्र के बाहर अपना रीडायरेक्ट कोड डालने से दूर हो जाएंगे। रिएक्ट राउटर के लिए कोड को देखते हुए , वे सर्वर साइड रेंडरिंग करते हैं या नहीं, इसके आधार पर componentWillMountया तो रीडायरेक्ट करते हैं componentDidMount। यहाँ नीचे कोड है, जो बहुत सरल है और आपको अपने रीडायरेक्ट लॉजिक को रखने के लिए अधिक आरामदायक महसूस करने में मदद कर सकता है।

import React, { PropTypes } from 'react'

/**
 * The public API for updating the location programatically
 * with a component.
 */
class Redirect extends React.Component {
  static propTypes = {
    push: PropTypes.bool,
    from: PropTypes.string,
    to: PropTypes.oneOfType([
      PropTypes.string,
      PropTypes.object
    ])
  }

  static defaultProps = {
    push: false
  }

  static contextTypes = {
    router: PropTypes.shape({
      history: PropTypes.shape({
        push: PropTypes.func.isRequired,
        replace: PropTypes.func.isRequired
      }).isRequired,
      staticContext: PropTypes.object
    }).isRequired
  }

  isStatic() {
    return this.context.router && this.context.router.staticContext
  }

  componentWillMount() {
    if (this.isStatic())
      this.perform()
  }

  componentDidMount() {
    if (!this.isStatic())
      this.perform()
  }

  perform() {
    const { history } = this.context.router
    const { push, to } = this.props

    if (push) {
      history.push(to)
    } else {
      history.replace(to)
    }
  }

  render() {
    return null
  }
}

export default Redirect

1

मेरा पिछला उत्तर स्केलेबल नहीं है। यहाँ मुझे लगता है कि अच्छा दृष्टिकोण है-

आपके रूट-

<Switch>
  <Route
    exact path="/"
    component={matchStateToProps(InitialAppState, {
      routeOpen: true // no auth is needed to access this route
    })} />
  <Route
    exact path="/profile"
    component={matchStateToProps(Profile, {
      routeOpen: false // can set it false or just omit this key
    })} />
  <Route
    exact path="/login"
    component={matchStateToProps(Login, {
      routeOpen: true
    })} />
  <Route
    exact path="/forgot-password"
    component={matchStateToProps(ForgotPassword, {
      routeOpen: true
    })} />
  <Route
    exact path="/dashboard"
    component={matchStateToProps(DashBoard)} />
</Switch>

आइडिया componentप्रॉप्स में एक रैपर का उपयोग करना है जो मूल घटक को लौटाएगा यदि किसी भी वस्तु की आवश्यकता नहीं है या पहले से ही प्रमाणित है अन्यथा डिफ़ॉल्ट घटक लौटाएगा जैसे लॉगिन।

const matchStateToProps = function(Component, defaultProps) {
  return (props) => {
    let authRequired = true;

    if (defaultProps && defaultProps.routeOpen) {
      authRequired = false;
    }

    if (authRequired) {
      // check if loginState key exists in localStorage (Your auth logic goes here)
      if (window.localStorage.getItem(STORAGE_KEYS.LOGIN_STATE)) {
        return <Component { ...defaultProps } />; // authenticated, good to go
      } else {
        return <InitialAppState { ...defaultProps } />; // not authenticated
      }
    }
    return <Component { ...defaultProps } />; // no auth is required
  };
};

अगर प्रमाणीकरण की आवश्यकता नहीं है, तो माडर्न को मेटस्टेटटाप्रॉप्स फंक्शन पास न करें, इसके साथ ही आप रूटऑन फ्लैग की आवश्यकता को समाप्त कर देंगे
धीरज

1

यहाँ सरल स्वच्छ संरक्षित मार्ग है

const ProtectedRoute 
  = ({ isAllowed, ...props }) => 
     isAllowed 
     ? <Route {...props}/> 
     : <Redirect to="/authentificate"/>;
const _App = ({ lastTab, isTokenVerified })=> 
    <Switch>
      <Route exact path="/authentificate" component={Login}/>
      <ProtectedRoute 
         isAllowed={isTokenVerified} 
         exact 
         path="/secrets" 
         component={Secrets}/>
      <ProtectedRoute 
         isAllowed={isTokenVerified} 
         exact 
         path="/polices" 
         component={Polices}/>
      <ProtectedRoute 
         isAllowed={isTokenVerified} 
         exact 
         path="/grants" component={Grants}/>
      <Redirect from="/" to={lastTab}/>
    </Switch>

isTokenVerified ऑथोराइज़ेशन टोकन की जांच करने के लिए एक विधि कॉल है जो मूल रूप से बूलियन देता है।


यह एक ही उपाय है जो मुझे काम करने के लिए मिला है यदि आप एक घटक या बच्चों को मार्ग पर भेज रहे हैं।
शॉन

नोट: मैंने अपने प्रोटेक्टराउट फंकिटोन में सिर्फ अपने isTokenVerified () को कॉल किया और मुझे सभी मार्गों पर isAllowed प्रोप को पारित करने की आवश्यकता नहीं थी।
शॉन

1

मैं इसे प्रतिक्रिया और टाइपस्क्रिप्ट के साथ कैसे हल करता है। आशा करता हूँ की ये काम करेगा !

import * as React from 'react';
import { Route, RouteComponentProps, RouteProps, Redirect } from 'react-router';

const PrivateRoute: React.SFC<RouteProps> = ({ component: Component, ...rest }) => {
    if (!Component) {
      return null;
    }
    const isLoggedIn = true; // Add your provider here
    return (
      <Route
        {...rest}
            render={(props: RouteComponentProps<{}>) => isLoggedIn ? (<Component {...props} />) : (<Redirect to={{ pathname: '/', state: { from: props.location } }} />)}
      />
    );
  };

export default PrivateRoute;








<PrivateRoute component={SignIn} path="/signin" />


0
const Root = ({ session }) => {
  const isLoggedIn = session && session.getCurrentUser
  return (
    <Router>
      {!isLoggedIn ? (
        <Switch>
          <Route path="/signin" component={<Signin />} />
          <Redirect to="/signin" />
        </Switch>
      ) : (
        <Switch>
          <Route path="/" exact component={Home} />
          <Route path="/about" component={About} />
          <Route path="/something-else" component={SomethingElse} />
          <Redirect to="/" />
        </Switch>
      )}
    </Router>
  )
}

0

मैं भी कुछ जवाब ढूंढ रहा था। यहां सभी उत्तर काफी अच्छे हैं, लेकिन उनमें से कोई भी जवाब नहीं देता है कि अगर उपयोगकर्ता इसे वापस खोलने के बाद आवेदन शुरू करता है तो हम इसका उपयोग कैसे कर सकते हैं। (मैं एक साथ कुकी का उपयोग करने के लिए कहने का मतलब था)।

कोई अलग PrivateRoute घटक बनाने की आवश्यकता नहीं है। नीचे मेरा कोड है

    import React, { Component }  from 'react';
    import { Route, Switch, BrowserRouter, Redirect } from 'react-router-dom';
    import { Provider } from 'react-redux';
    import store from './stores';
    import requireAuth from './components/authentication/authComponent'
    import SearchComponent from './components/search/searchComponent'
    import LoginComponent from './components/login/loginComponent'
    import ExampleContainer from './containers/ExampleContainer'
    class App extends Component {
    state = {
     auth: true
    }


   componentDidMount() {
     if ( ! Cookies.get('auth')) {
       this.setState({auth:false });
     }
    }
    render() {
     return (
      <Provider store={store}>
       <BrowserRouter>
        <Switch>
         <Route exact path="/searchComponent" component={requireAuth(SearchComponent)} />
         <Route exact path="/login" component={LoginComponent} />
         <Route exact path="/" component={requireAuth(ExampleContainer)} />
         {!this.state.auth &&  <Redirect push to="/login"/> }
        </Switch>
       </BrowserRouter>
      </Provider>);
      }
     }
    }
    export default App;

और यहां ऑर्टकम्पोनेंट है

import React  from 'react';
import { withRouter } from 'react-router';
import * as Cookie from "js-cookie";
export default function requireAuth(Component) {
class AuthenticatedComponent extends React.Component {
 constructor(props) {
  super(props);
  this.state = {
   auth: Cookie.get('auth')
  }
 }
 componentDidMount() {
  this.checkAuth();
 }
 checkAuth() {
  const location = this.props.location;
  const redirect = location.pathname + location.search;
  if ( ! Cookie.get('auth')) {
   this.props.history.push(`/login?redirect=${redirect}`);
  }
 }
render() {
  return Cookie.get('auth')
   ? <Component { ...this.props } />
   : null;
  }
 }
 return  withRouter(AuthenticatedComponent)
}

नीचे मैंने ब्लॉग लिखा है, आप वहां और अधिक गहराई से स्पष्टीकरण प्राप्त कर सकते हैं।

ReactJS में संरक्षित मार्ग बनाएं


0

समाधान जो अंततः मेरे संगठन के लिए सबसे अच्छा काम करता है, नीचे विस्तृत है, यह सिर्फ sysadmin मार्ग के लिए रेंडर पर एक चेक जोड़ता है और उपयोगकर्ता को एप्लिकेशन के एक अलग मुख्य पथ पर पुनर्निर्देशित करता है यदि उन्हें पृष्ठ में होने की अनुमति नहीं है।

SysAdminRoute.tsx

import React from 'react';
import { Route, Redirect, RouteProps } from 'react-router-dom';
import AuthService from '../services/AuthService';
import { appSectionPageUrls } from './appSectionPageUrls';
interface IProps extends RouteProps {}
export const SysAdminRoute = (props: IProps) => {
    var authService = new AuthService();
    if (!authService.getIsSysAdmin()) { //example
        authService.logout();
        return (<Redirect to={{
            pathname: appSectionPageUrls.site //front-facing
        }} />);
    }
    return (<Route {...props} />);
}

हमारे कार्यान्वयन के लिए 3 मुख्य मार्ग हैं, सार्वजनिक सामना / साइट, क्लाइंट / ऐप में लॉग इन, और sys / sysmmin पर व्यवस्थापक उपकरण। आप अपने 'आत्मीयता' के आधार पर पुनर्निर्देशित हो जाते हैं और यह पृष्ठ है / sysadmin पर।

SysAdminNav.tsx

<Switch>
    <SysAdminRoute exact path={sysadminUrls.someSysAdminUrl} render={() => <SomeSysAdminUrl/> } />
    //etc
</Switch>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.