React Router 4'te kimliği doğrulanmış yollar nasıl uygulanır?


122

Kimliği doğrulanmış yolları uygulamaya çalışıyordum, ancak React Router 4'ün artık bunun çalışmasını engellediğini gördüm:

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

Hata şudur:

Uyarı: Sen kullanmamalısınız <Route component>ve <Route children>aynı rotada; <Route children>göz ardı edilecek

Bu durumda, bunu uygulamanın doğru yolu nedir?

react-router(V4) belgelerinde görünür , şöyle bir şey önerir:

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

Ancak bunu, bir grup güzergahı birlikte gruplayarak başarmak mümkün mü?


GÜNCELLEME

Tamam, biraz araştırdıktan sonra şunu buldum:

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()Yanlış hissettiren bir eylemi göndermek doğru mu ? componentDidMountYa da başka bir kanca ile gerçekten doğru görünmüyor mu?


Sunucu tarafı oluşturma kullanılmıyorsa, componentWillMount üzerinde yapılacak en iyisi.
mfahadi

@mfahadi, girdiniz için teşekkürler. Henüz SSR kullanmıyorum, ancak gelecekte kullanmak istersem, onu render halinde tutacak mıyım? Ayrıca, kullanıcı yeniden yönlendirilirse componentWillMount, oluşturulan çıktıyı bir saniye bile olsa görebilirler mi?
Jiew Meng

Bunun componentWillMount()SSR'de çağrılmadığını söylediğim için gerçekten üzgünüm , çağrılmayan o componentDidMount(). daha componentWillMount()önce çağrıldığı gibi , render()kullanıcı yeni bileşenle ilgili hiçbir şey görmeyecektir. bu yüzden kontrol etmek için en iyi yerdir.
mfahadi

1
<Redirect to="/auth">
Gönderme

Yanıtlar:


239

RedirectBileşeni kullanmak isteyeceksiniz . Bu soruna birkaç farklı yaklaşım var. İşte sevdiğim bir tanesi, bir authedpervane alan ve daha sonra bu propsa göre işleyen bir PrivateRoute bileşenine sahip .

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

Şimdi Routeseninkiler böyle bir şeye benzeyebilir

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

Hala kafanız karıştıysa, yardımcı olabilecek bu yazıyı yazdım - React Router v4 ile korumalı yollar ve kimlik doğrulama


2
Oh bu benim çözümüme benziyor, ama kullanıyor <Redirect />. <Redirect />Benim durumumda sorun redux ile çalışmıyor gibi görünüyor? Bir eylem göndermem gerekiyor
Jiew Meng

3
Neden bilmiyorum ama eklemek state: {from: props.location}}}bir maximum call stack exceeded. Onu çıkarmak zorunda kaldım. Bu seçeneğin neden yararlı olduğunu açıklar mısınız @Tyler McGinnis?
martpie

@KeitIG ​​Bu tuhaf. Yararlıdır çünkü size nereden geldiğinizi söyler. Örneğin, kullanıcının kimliğini doğrulamasını istiyorsanız, kimlik doğrulamasını yaptıktan sonra, yeniden yönlendirmeden önce erişmeye çalıştıkları sayfaya geri götürün.
Tyler McGinnis

6
@faraz Bu ({component: Component, ...rest})sözdizimini açıklar . Ben de aynı soruyu sormuştum! stackoverflow.com/a/43484565/6502003
protoEvangelion

2
@TylerMcGinnis Props'u bileşene aktarmak için render işlevini kullanmamız gerekirse ne olur?
C Bauer

16

Çözüm için Tnx Tyler McGinnis. Fikrimi Tyler McGinnis fikrinden yapıyorum.

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

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

Bunu böyle uygulayabilirsin

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

kararFunc yalnızca doğru veya yanlış döndüren bir işlev

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

8

(Durum yönetimi için Redux kullanma)

Kullanıcı herhangi bir url'ye erişmeye çalışırsa, önce erişim belirtecinin mevcut olup olmadığını kontrol edeceğim, eğer oturum açma sayfasına yönlendirmiyorsa, Kullanıcı oturum açma sayfasını kullanarak oturum açtığında, bunu yerel depoda ve yeniden düzenleme durumumuzda saklarız. (yerel depolama veya tanımlama bilgileri..bu konuyu şimdilik bağlamın dışında tutuyoruz).
çünkü yeniden düzenleme durumu güncellendi ve özel yollar yeniden işlenecek. Artık erişim jetonumuz var, bu yüzden ana sayfaya yönlendireceğiz.

Kodu çözülen yetkilendirme yük verilerini yeniden düzenleme durumunda depolayın ve içeriğe tepki vermek için iletin. (Bağlam kullanmak zorunda değiliz, ancak iç içe geçmiş alt bileşenlerimizin herhangi birinde yetkilendirmeye erişmek, her bir alt bileşeni yeniden düzenlemeye bağlamak yerine bağlamdan erişimi kolaylaştırır) ..

Özel roller gerektirmeyen tüm rotalara giriş yapıldıktan sonra doğrudan erişilebilir. Yönetici gibi bir role ihtiyaç duyarsa (yetkisiz bileşene yönlendirmiyorsa, istenen role sahip olup olmadığını kontrol eden korumalı bir rota yaptık)

benzer şekilde, düğmeyi veya role bağlı bir şeyi devre dışı bırakmanız gerektiğinde bileşeninizden herhangi birinde.

basitçe bu şekilde yapabilirsin

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>

Öyleyse, kullanıcı yerel depoya sahte jeton eklemeye çalışırsa ne olur? Erişim belirtecimiz olduğu için, ev bileşenine yönlendireceğiz. Ev bileşenim verileri almak için dinlenme çağrısı yapacak, jwt token sahte olduğundan, dinlenme çağrısı yetkisiz kullanıcıyı döndürecektir. Bu yüzden oturumu kapatıyorum (bu, yerel depolamayı temizleyecek ve tekrar giriş sayfasına yönlendirecektir). Ana sayfada statik veriler varsa ve herhangi bir API çağrısı yapmıyorsa (o zaman, ana sayfayı yüklemeden önce jetonun GERÇEK olup olmadığını kontrol edebilmeniz için arka uçta token-doğrulama api çağrısına sahip olmanız gerekir)

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];
};

ÇÖZÜLMÜŞ JWT TOKEN NUMUNESİ

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

Ve doğrudan erişimi nasıl yönetiyorsunuz Signin? Bir kullanıcı oturum açmadığını biliyorsa, Oturum Açma'ya doğrudan erişim seçeneğine sahip olmalıdır, değil mi?
carkod

@carkod ... Varsayılan olarak, herhangi bir rotaya erişmeye çalışırsa, oturum açma sayfasına yönlendirilecektir ... (belirteci olmayacağı için)
Hemanthvrm

@carkod .. kullanıcı oturumu kapatmayı tıkladığında veya jwt yenileme belirtecimin süresi dolar .. yerel depolamayı temizlediğimde ve pencereyi yenilediğimde oturum kapatma işlevini yapıyorum ... bu nedenle yerel depolama jetona sahip olmayacak ... otomatik olarak oturum açma sayfasına yönlendirecek
Hemanthvrm

redux kullananlar için daha iyi bir versiyonuna sahibim ... cevabımı birkaç gün içinde güncelleyeceğim..thanks -
Hemanthvrm

3

react-yönlendirici-dom'u yükle

daha sonra biri geçerli kullanıcılar ve diğeri geçersiz kullanıcılar için iki bileşen oluşturun.

bunu app.js'de deneyin

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
Rota başına mı? Bu ölçeklenmeyecek.
Jim G.

3

@Tyler McGinnis'in cevabına göre . ES6 sözdizimini ve sarmalanmış bileşenlerle iç içe geçmiş yolları kullanarak farklı bir yaklaşım yaptım :

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

Ve bunu kullanarak:

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

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

2

Bir süredir biliyorum ama özel ve halka açık rotalar için bir npm paketi üzerinde çalışıyorum .

Özel bir rota nasıl yapılır:

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

Ayrıca, yalnızca yetkisi olmayan kullanıcıların erişebileceği Genel rotalar da oluşturabilirsiniz.

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

Umut ediyorum bu yardım eder!


Tüm içe aktarma ve sarmalamaları içeren daha fazla örnek, örneğin ana App.js'de 2 genel yol, 2 özel yol ve 2 PropsRoute sağlayabilir misiniz? teşekkür ederim
MH

2

Kullanarak uyguladım

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

kimlik doğrulama props bileşenlere, örneğin hangi kullanıcı durumunun değiştirilebileceğini kullanarak kaydolmaya aktarılacaktır. Komple Uygulama Rotaları-

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

Projenin tamamını buradan kontrol edin: https://github.com/varunon9/hello-react


1

Görünüşe göre kendi bileşeninizi oluşturmak ve ardından render yöntemini göndermek konusunda tereddütleriniz mi var? Sadece bileşenin renderyöntemini kullanarak her ikisinden de kaçınabilirsiniz <Route>. <AuthenticatedRoute>Gerçekten istemediğiniz sürece bir bileşen oluşturmanıza gerek yok . Aşağıdaki kadar basit olabilir. Not {...routeProps}emin özelliklerini göndermeye devam yayılmış verme <Route>(çocuk bileşenine bileşen aşağı <MyComponent>bu durumda).

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

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

} />

Bkz Yönlendirici V4 belgelerine hale Tepki

Özel bir bileşen oluşturmak istediyseniz, doğru yoldasınız gibi görünür. React Router V4 tamamen bildirimsel yönlendirme olduğu için ( açıklamada öyle yazıyor) Yönlendirme kodunuzu normal bileşen yaşam döngüsünün dışına koymanın yanına kalmayacağınızı düşünmüyorum. React Router'ın koduna bakıldığında , yönlendirmeyi sunucu tarafı işleme olup olmadığına bağlı olarak ya componentWillMountda bunlardan birinde gerçekleştirirler componentDidMount. İşte aşağıdaki kod oldukça basittir ve yönlendirme mantığınızı nereye koyacağınız konusunda kendinizi daha rahat hissetmenize yardımcı olabilir.

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

Önceki cevabım ölçeklenebilir değil. İşte iyi bir yaklaşım olduğunu düşündüğüm şey:

Rotalarınız-

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

Fikir, componentherhangi bir yetkilendirme gerekmiyorsa veya zaten doğrulanmışsa orijinal bileşeni döndürecek bir sarmalayıcı kullanmaktır , aksi takdirde varsayılan bileşen, örneğin Oturum Açma döndürür.

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

kimlik doğrulaması gerekmiyorsa, bileşeni matchStateToProps işlevine geçirmeyin, bununla routeOpen bayrağı ihtiyacını ortadan kaldırırsınız
Dheeraj

1

İşte basit, temiz korumalı rota

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 yetkilendirme belirtecini kontrol etmek için bir yöntem çağrısıdır, temelde boole döndürür.


Rotaya bir Bileşen veya Çocuk geçiriyorsanız burada işe yaradığını bulduğum tek çözüm budur.
Shawn

Not: ProtectedRoute işlevimde isTokenVerified () 'i aradım ve tüm rotalarda isAllowed prop'unu geçirmem gerekmedi.
Shawn

1

İşte React ve Typescript ile bunu nasıl çözdüm. Umarım yardımcı olur !

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

Ben de bir cevap arıyordum. Burada tüm cevaplar oldukça iyi, ancak hiçbiri kullanıcı uygulamayı açtıktan sonra uygulamayı başlatırsa onu nasıl kullanabileceğimizi cevaplamıyor. (Çerezi birlikte kullanmayı söylemek istemiştim).

Hatta farklı bir privateRoute Bileşeni oluşturmanıza gerek yok. Kodum aşağıdadır

    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;

Ve işte authComponent

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

Aşağıda blog yazdım, orada da daha ayrıntılı açıklamalar alabilirsiniz.

ReactJS'de korumalı yollar oluşturun


0

Nihayetinde kuruluşum için en iyi şekilde çalışan çözüm aşağıda ayrıntılı olarak açıklanmıştır, yalnızca sysadmin rotası için render üzerinde bir kontrol ekler ve sayfada bulunmalarına izin verilmiyorsa kullanıcıyı uygulamanın farklı bir ana yoluna yönlendirir.

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

Uygulamamız için 3 ana yol vardır: herkese açık / site, oturum açılmış istemci / uygulama ve / sysadmin'de sys yönetici araçları. "Doğruluğunuza" göre yeniden yönlendirilirsiniz ve bu / sysadmin adresindeki sayfadır.

SysAdminNav.tsx

<Switch>
    <SysAdminRoute exact path={sysadminUrls.someSysAdminUrl} render={() => <SomeSysAdminUrl/> } />
    //etc
</Switch>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.