প্রতিক্রিয়া রাউটার 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()এটিতে কোনও ক্রিয়া প্রেরণে সঠিক নয় feels এটি সত্যিই সঠিক componentDidMountবা অন্য কোনও হুক হয় না বলে মনে হচ্ছে ?


সার্ভার সাইড রেন্ডারিং ব্যবহার না করা হলে কমপোনাটওয়িলমাউন্টে করা ভাল।
এমফাহাদী

@ এমফাহাদী, ইনপুট দেওয়ার জন্য আপনাকে ধন্যবাদ আমি এখনও এসএসআর ব্যবহার করছি না, তবে আমি যদি ভবিষ্যতে ব্যবহার করতে চাই, আমি কি এটি রেন্ডার করে রাখব? এছাড়াও যদি ব্যবহারকারীকে পুনঃনির্দেশিত করা হয় componentWillMount, তারা কি কখনও বিভক্ত দ্বিতীয়বারের জন্যও রেন্ডার আউটপুট দেখতে পাবে?
জিউ মেনগ

componentWillMount()এসএসআর-তে ডাকা হয় নি বলে আমি সত্যিই দুঃখিত componentDidMount()that যেমন componentWillMount()আগে বলা হয় render(), তাই ব্যবহারকারী নতুন উপাদানগুলির কিছুই দেখতে পাবে না। সুতরাং এটি যাচাই করার জন্য সেরা জায়গা।
এমফাহাদী

1
আপনি প্রেরণের ক্রিয়াটি কল করার পরিবর্তে <Redirect to="/auth"> ডক্স থেকে কেবলমাত্র ব্যবহার করতে পারেন
ফুজাইল এল'কর্ডার

উত্তর:


238

আপনি Redirectউপাদানটি ব্যবহার করতে চাইছেন । এই সমস্যাটির জন্য কয়েকটি পৃথক পদ্ধতি রয়েছে। এখানে আমার পছন্দ মতো একটি প্রাইভেটরোট উপাদান রয়েছে যা কোনও 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 />আমার ক্ষেত্রে রিডুএক্সের সাথে কাজ করবে বলে মনে হচ্ছে না? আমাকে একটি ক্রিয়া পাঠাতে হবে
জিউ মেনগ

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

(রাষ্ট্র পরিচালনার জন্য রেডাক্স ব্যবহার করা)

ব্যবহারকারী যদি কোনও ইউআরএল অ্যাক্সেস করার চেষ্টা করেন, প্রথমে আমি লগইন পৃষ্ঠায় পুনর্নির্দেশ না করে অ্যাক্সেস টোকেন উপলব্ধ কিনা তা যাচাই করতে যাচ্ছি, একবার ব্যবহারকারী লগইন পৃষ্ঠা ব্যবহার করে লগইন করে, আমরা সেইটিকে স্থানীয় স্টোরেজে পাশাপাশি আমাদের রিডেক্স অবস্থায় সংরক্ষণ করি। (স্থানীয় স্টোরেজ বা কুকিজ..আমাদের জন্য এই বিষয়টিকে প্রসঙ্গের বাইরে রাখি)।
যেহেতু আপডেটেড এবং প্রাইভেটরউটিস হিসাবে রিডেক্স রাজ্যটি পুনরায় সরবরাহ করা হবে। এখন আমাদের অ্যাক্সেস টোকেন রয়েছে তাই আমরা হোম পৃষ্ঠায় পুনর্নির্দেশ করব।

ডিকোডযুক্ত অনুমোদনের পেডলোড ডেটা পাশাপাশি রিডুএক্স অবস্থায় সঞ্চয় করুন এবং প্রসঙ্গে প্রতিক্রিয়া জানাতে এটি পাস করুন। (আমাদের প্রসঙ্গ ব্যবহার করতে হবে না তবে আমাদের যে কোনও নেস্টেড শিশু উপাদানগুলিতে অনুমোদনের অ্যাক্সেসের জন্য প্রসঙ্গ থেকে অ্যাক্সেস করা সহজ করে প্রতিটি শিশু উপাদানকে রেডএক্সের সাথে সংযুক্ত করে) ..

যে সমস্ত রুটে বিশেষ ভূমিকার প্রয়োজন নেই সরাসরি লগইন করার পরে অ্যাক্সেস করা যায় .. যদি অ্যাডমিনের মতো ভূমিকার প্রয়োজন হয় (আমরা একটি সুরক্ষিত রুট তৈরি করেছি যা অননুমোদিত উপাদানগুলিতে পুনর্নির্দেশ না করে তবে তার ইচ্ছা ছিল কিনা তা পরীক্ষা করে নেওয়া হয়)

একইভাবে আপনার যে কোনও উপাদানতে যদি আপনাকে বোতাম বা ভূমিকার উপর ভিত্তি করে কিছু অক্ষম করতে হয়।

সহজভাবে আপনি এইভাবে করতে পারেন

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>

সুতরাং যদি ব্যবহারকারী লোকস্টোরেজে ডামি টোকেন sertোকানোর চেষ্টা করেন। আমাদের কাছে অ্যাক্সেস টোকেন রয়েছে তাই আমরা হোম উপাদানগুলিতে পুনর্নির্দেশ করব। আমার বাড়ির উপাদান ডেটা দখল করার জন্য বিশ্রাম কল করবে, যেহেতু 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];
};

JWT টোকেন নমুনা বাতিল

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

এবং আপনি কীভাবে সরাসরি অ্যাক্সেস পরিচালনা করবেন Signin? যদি কোনও ব্যবহারকারী জানেন যে তিনি সাইন ইন নন, তবে তার সরাসরি সাইন ইন অ্যাক্সেস করার একটি বিকল্প থাকা উচিত, তাই না?
কারকড

@ কারকোড ... ডিফল্টরূপে যদি তিনি কোনও রুটে অ্যাক্সেস করার চেষ্টা করেন তবে তাকে সাইন ইন পৃষ্ঠাতে পুনর্নির্দেশ করা হবে ... (যেহেতু সে টোকেন
রাখবে না

@ কারকোড .. একবার ব্যবহারকারী লগআউটে ক্লিক করেন বা অন্যথায় আমার jwt রিফ্রেশ টোকেনের মেয়াদ শেষ হয়ে যায় .. আমি লগআউট ফাংশনটি কল করি যেখানে আমি লোকালস্টোরেজ এবং উইন্ডো রিফ্রেশ করি ... সুতরাং স্থানীয় স্টোরেজটি টোকেন রাখবে না ... এটি স্বয়ংক্রিয়ভাবে লগইন পৃষ্ঠায় পুনঃনির্দেশ করবে
হেমন্তভ্রিম

যারা রিডুএক্স ব্যবহার করছেন তাদের কাছে আমার এটির আরও ভাল সংস্করণ আছে..আর কয়েকদিনের মধ্যে আমার উত্তরটি আপডেট করবেন..ধন্যবাদ -
হেমন্তভর্ম

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

আমি জানি এটি কিছুক্ষণ হয়ে গেছে তবে আমি বেসরকারী এবং পাবলিক রুটের জন্য এনপিএম প্যাকেজে কাজ করছি ।

এখানে একটি ব্যক্তিগত রুট কীভাবে করা যায় তা এখানে:

<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 প্রোপস রুটে? আপনাকে ধন্যবাদ
এম এইচ

2

আমি ব্যবহার করে বাস্তবায়ন করেছি -

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

প্রমাণীকরণযোগ্য প্রপগুলি উপাদানগুলিতে পাস করা হবে যেমন সাইনআপ ব্যবহার করে ব্যবহারকারীর রাজ্য পরিবর্তন করা যেতে পারে। সম্পূর্ণ AppRoutes-

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 ডকুমেন্টেশন রেন্ডার

আপনি যদি কোনও উত্সর্গীকৃত উপাদান তৈরি করতে চান না, তবে দেখে মনে হচ্ছে আপনি সঠিক পথে আছেন। যেহেতু প্রতিক্রিয়া রাউটার ভি 4 নির্ভেজালভাবে ঘোষিত রাউটিং (এটি বর্ণনায় সঠিকভাবে বলে) আমি মনে করি না যে আপনি আপনার পুনঃনির্দেশ কোডটি সাধারণ উপাদান লাইফসাইকের বাইরে রেখে চলে যাবেন। এ খুঁজছি কোড প্রতিক্রিয়া রাউটার নিজেই , তারা পুনর্নির্দেশ সঞ্চালন পারেন 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 অনুমোদনের টোকেন চেক করার জন্য একটি পদ্ধতি কল যা মূলত এটি বুলিয়ান দেয়।


আপনি যদি কোনও অংশ বা শিশুদের পথে যাচ্ছেন তবে এখানে কাজ করার জন্য এটিই একমাত্র সমাধান।
শান

দ্রষ্টব্য: আমি কেবলমাত্র আমার প্রোটেক্টেডরউটে ফানসিটনে আমার isTenen যাচাইকৃত () ফোন করেছি এবং সমস্ত রুটে আমার অ্যাসোলেড প্রপ পাস করার দরকার নেই।
শান

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

আমিও কিছু উত্তর খুঁজছিলাম। এখানে সমস্ত উত্তরগুলি বেশ ভাল, তবে ব্যবহারকারীরা যদি এটির পুনরায় খোলার পরে অ্যাপ্লিকেশন শুরু করে তবে আমরা কীভাবে এটি ব্যবহার করতে পারি তার উত্তর দেয় না। (আমি বলতে চাইছিলাম একসাথে কুকি ব্যবহার করে)।

এমনকি আলাদা বেসরকারী রুট উপাদান তৈরি করার প্রয়োজন নেই। নীচে আমার কোড দেওয়া আছে

    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;

এবং এখানে authComp घटक

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)
}

আমি ব্লগ লিখেছি নীচে, আপনি পাশাপাশি আরও গভীরতার ব্যাখ্যা পেতে পারেন।

রিঅ্যাক্টজেএস-এ সুরক্ষিত রুট তৈরি করুন


0

সমাধানটি যা শেষ পর্যন্ত আমার সংস্থার পক্ষে সবচেয়ে ভাল কাজ করেছে তা নীচে বিস্তারিত রয়েছে, এটি সিসাদমিন রুটের জন্য রেন্ডারের উপর একটি চেক যুক্ত করে এবং ব্যবহারকারীকে যদি পৃষ্ঠাটিতে না যাওয়ার অনুমতি দেয় তবে অ্যাপ্লিকেশনটির একটি পৃথক মূল পথে পুনঃনির্দেশ করে।

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 টি প্রধান রুট রয়েছে, জনসাধারণের মুখোমুখি / সাইট, লগ ইন করা ক্লায়েন্ট / অ্যাপ্লিকেশন এবং সিসাদমিনে সিস্টেম অ্যাডমিন সরঞ্জাম রয়েছে। আপনি আপনার 'প্রমাণীকরণের' ভিত্তিতে পুনঃনির্দেশিত হন এবং এটি সিসাদমিনে পৃষ্ঠা।

SysAdminNav.tsx

<Switch>
    <SysAdminRoute exact path={sysadminUrls.someSysAdminUrl} render={() => <SomeSysAdminUrl/> } />
    //etc
</Switch>
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.