Реагировать js PrivateRoute показать скрыть компонент панели мониторинга на основе веб-токена JSON и вызвать вызов - PullRequest
0 голосов
/ 27 марта 2019

Мне нужна помощь, когда пользователь переходит на URL http://localhost:3000/dashboard, если администратор уже вошел в систему до того, как он сможет увидеть панель инструментов, мы просто проверим токен в своем локальном хранилище?я проверяю этот веб-токен JSON, отправляя его в приложение node.js, чтобы проверить, хорошо ли мы отправляем статус 200, и если его плохой токен, мы отправляем статус 401 и на основании статуса мы устанавливаем для Частного маршрута значение true или false,функция извлечения готова, но я не могу найти способ интегрировать ее

это структура файлов приложения

my-app/
  README.md
  node_modules/
  package.json
  public/
    index.html
    favicon.ico
  src/
     |components/
      |Clien/
        |Home.js
        |Home.css
        |Header.js
        |Footer.js
      |admin/
        |Auth.js
        |PrivateRoute.js
        |Admin.js
        |Dashboard.js
        |Dashboard.css
      App.css
      App.js
      index.css
      index.js
      logo.svg

это функция, которую я использую для проверки наличия JWT в локальном хранилище и проверкитокен, отправляющий его на сервер, возвращает ответ и, основываясь на ответе, хочу показать панель управления или перенаправить к форме входа администратора

, сейчас все работает нормально, но только если я вручную изменяю isAuthenticated (в классе аутентификации)Я не могу найти способ сделать проверку, основанную на ответе выборки с сервера, я не уверен, должен ли я использовать функцию в классе Auth как функцию, или я должен создать Компонент с состоянием и componentDidMount ()

пожалуйста, ведите меня, как я новичок:

это функция

componentDidMount(){
        //get token from local storage if there is one
        const jwttoken = localStorage.getItem('jwttoken');
        const bearer = 'Bearer '+ jwttoken;
           const data = new FormData();
           // get the website backend main url from .env
           const REACT_APP_URL = process.env.REACT_APP_URL
           fetch(`${REACT_APP_URL}/api/auth/verify`, {
                method: 'POST',
                headers: {
                    'Accept': 'application/json',
                    'Authorization': bearer,
                },
                body: data
           }).then( (res)=> {
               if (res.status === 401) {
                   res.json()
                   .then( (res)=> {
                       this.setState({
                        isLogedout: true,
                        })
                       localStorage.removeItem('jwttoken');
                   })
               } else if (res.status === 200) {
                   res.json()
                   .then((res)=> {
                    this.setState({
                         isLogedout: false,
                         adminEmail: res.adminEmail
                         })
                         this.props.history.push("/dashboard"); 

                   })
               }else{
                this.setState({
                    isLogedout: true,
                    })
                   localStorage.removeItem('jwttoken');
               }
           }).catch((err) => {
            // console.log(err)
            })

    }

этоКомпонент приложения, где все маршруты

import React, { Component } from "react";
import { Route, } from "react-router-dom";
// import Auth from "./Components/Admin/Auth"


import logo from "./Components/img/logo.jpg";
import headerimg from "./Components/img/header.png";
import "./App.css";
import Home from "./Components/Home";
import Dashboard from "./Components/Admin/Dashboard";
import Articles from "./Components/Articles";
import ArticleId from "./Components/ArticleId";
import Admin from "./Components/Admin/Admin.js";
import{ PrivateRoute} from "./Components/Admin/PrivateRoute.js";


class App extends Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      webiste: {
        title: "Website title",
        headerimg: headerimg,
        altheaderimg: "website header image",
        logo: logo,
        logotitle: "website logo "
      },

    };
  }


  render() {
    return (
      <div className="app-container">
        <Route exact path='/' render={(props) => <Home {...props} setTab={"home"} />} />
        <Route exact path='/home' render={(props) => <Home {...props} setTab={"home"} />} />
        <Route path='/articles' render={(props) => <Articles {...props} setArticle={"false"} />} />
        <Route path='/article/:id' render={(props) => <ArticleId {...props.match.params} setArticle={"false"} />} />

        <Route exact path='/services' render={(props) => <Home {...props} setTab={"services"} />} />
        <Route exact path='/events' render={(props) => <Home {...props} setTab={"events"} />} />
        <Route exact path='/about' render={(props) => <Home {...props} setTab={"about"} />} />
        <Route exact path='/contact' render={(props) => <Home {...props} setTab={"contact"} />} />

        <Route exact path='/admin' component={Admin} />
        <PrivateRoute exact path="/dashboard" component={Dashboard}  />

      </div>

    );
  }
}

export default App;

это: PrivateRoute Component

import React, { Component }  from  "react";
import { Route, Redirect, } from "react-router-dom";
import Auth from "./Auth"


export const PrivateRoute = ({ component: Component, ...rest }) => {
  return (
    <Route {...rest} render={(props) => (
      Auth.isAuthenticated() === true
        ? <Component {...props} />
        : <Redirect to='/admin' />
    )} />
      )
}

это: класс аутентификации

class Auth {

    constructor() {
        this.authenticated = true;
    }

    login(cb) {
        this.authenticated = true;
        cb();
    }

    logout(cb) {
        this.authenticated = false;
        cb();
    }

    isAuthenticated() { 
        return this.authenticated;    

    }
}

export default new Auth();

это:Компонент панели инструментов, извините, он огромный, поэтому я не включаю все, что для меня важно, как показать и скрыть его в PrivateRouter

class Dashboard extends Component {
  constructor(props) {
    super(props);
    this.state = {
      Articles: true,
      AddArticles: false,
      Messages: false,
      Services: false,
      Events: false,
      About: false,
      AdminContact: false,
      AdminAddEvent: false,
      WebsiteInfo: false,

      isLogedin: '',

      //dynamic className
      classArticles: "admin-side-bar-button-selected",
      classAddArticle: "admin-side-bar-button",
      classEvents: "admin-side-bar-button",
      classAddEvents: "admin-side-bar-button",
      classServices: "admin-side-bar-button",
      classAbout: "admin-side-bar-button",
      classContact: "admin-side-bar-button",
      classWebsiteInfo: "admin-side-bar-button",

    };
  }

  render() {
    return (
      <div>
      < div key="1" className="all-dashboard-container" >

        <div className="header-dashboard">
          <AdminHeader logout={this.logout} />
        </div>

        <div className="dashboard-container">
          <div className="side-dashboard">
            <button className={this.state.classArticles} onClick={this.showArticles}>Articles</button>
            <div className="hr"></div>
            <button className={this.state.classAddArticle} onClick={this.showAddArticles}>Add Aricle</button>
            <div className="hr"></div>
            <button className={this.state.classEvents} onClick={this.showEvents}>Events </button>
            <div className="hr"></div>
            <button className={this.state.classAddEvents} onClick={this.showAdminAddEvent}>Add Events</button>
            <div className="hr"></div>
            <button className={this.state.classServices} onClick={this.showServices}>Services </button>
            <div className="hr"></div>
            <button className={this.state.classAbout} onClick={this.showAbout}>About </button>
            <div className="hr"></div>
            <button className={this.state.classContact} onClick={this.showContact}>Contact</button>
            <div className="hr"></div>
            <button className={this.state.classWebsiteInfo} onClick={this.showWebsiteInfo}>Website Info </button>
            <div className="hr"></div>
          </div>

          <div className="body-dashboard">
            <div>
              <div>
                {this.state.Articles && <div> <AdminPublishedArticles /> </div>}
              </div>

              <div>
                {this.state.AddArticles && <div> <AdminAddArticle /> </div>}
              </div>

              <div>
                {this.state.AdminAddEvent && <div> <AdminAddEvent /> </div>}
              </div>

              <div>
                {this.state.Events && <div> <AdminPublishedEvents /> </div>}
              </div>

              <div>
                {this.state.Services && <div> <AdminServices /> </div>}
              </div>

              <div>
                {this.state.About && <div> <AdminAbout /> </div>}
              </div>

              <div>
                {this.state.AdminContact && <div> <AdminContact/> </div>}
              </div>

              <div>
                {this.state.WebsiteInfo && <div> <WebsiteInfo /> </div>}
              </div>

            </div>

          </div>
        </div>

        <div> <Footer/></div>

      </div>
      </div>
    );
  }
}

export default Dashboard;

это компонент администратора, его форма входа

import React, { Component } from 'react';
import "./css/Admin.css";
import Auth from './Auth';
class Admin extends Component {
    constructor(props) {
        super(props);
        this.state = { 
            adminEmail: '',
            password: '',
            loginError: false,
            isLogedout: null

         }
    }

    componentDidMount(){
        //get token from local storage if there is one
        const jwttoken = localStorage.getItem('jwttoken');
        const bearer = 'Bearer '+ jwttoken;
           const data = new FormData();
           // get the website backend main url from .env
           const REACT_APP_URL = process.env.REACT_APP_URL
           fetch(`${REACT_APP_URL}/api/auth/verify`, {
                method: 'POST',
                headers: {
                    'Accept': 'application/json',
                    'Authorization': bearer,
                },
                body: data
           }).then( (res)=> {
               if (res.status === 401) {
                   res.json()
                   .then( (res)=> {
                       this.setState({
                        isLogedout: true,
                        adminEmail: res.adminEmail
                        })
                       localStorage.removeItem('jwttoken');
                   })
               } else if (res.status === 200) {
                   res.json()
                   .then((res)=> {
                    this.setState({
                         isLogedout: false,
                         adminEmail: res.adminEmail
                         })
                         this.props.history.push("/dashboard"); 

                   })
               }else{
                this.setState({
                    isLogedout: true,
                    adminEmail: res.adminEmail
                    })
                   localStorage.removeItem('jwttoken');
               }
           }).catch((err) => {
            // console.log(err)
            })

    }

    handleSubmit = (event) => {
        event.preventDefault();
           const data = new FormData();
           data.append('email', this.state.email);
           data.append('password', this.state.password);
           // get the website backend main url from .env
           const REACT_APP_URL = process.env.REACT_APP_URL
           fetch(`${REACT_APP_URL}/api/auth/login`, {
                method: 'POST',
                headers: {
                    'Accept': 'application/json',
                   //  'Content-Type': 'application/x-www-form-urlencoded'
                },
                body: data
           }).then( (response)=> {
               if (response.status === 401) {
                   response.json()
                   .then( (res)=> {
                       console.log(res)
                       this.setState({ loginError: true })
                   })
               } else if (response.status === 200) {
                   response.json()
                   .then((res) => {localStorage.setItem('jwttoken', res) })
                   .then((res)=> {
                       Auth.login(()=>{
                          this.props.history.push("/dashboard"); 
                       })

                   })
               }
           }).catch((err) => {
            err.json()
            .then(console.log(err))
            })
      }

    changeEventEmail = (event) => {
        this.setState({
            email: event.target.value,
            loginError: false
          });
    }

    changeEventPassword = (event) => {
        this.setState({
             password: event.target.value,
             loginError: false
             });
      }


    render() {
        return (
            <div>
             { this.state.isLogedout &&   
            <div className="admin-login-container">

                <form className="admin-login-form" onSubmit={this.handleSubmit}>
                    <label>Email</label>
                    <input type="text" onChange={this.changeEventEmail} value={this.state.email} required />
                    <label >Password </label>
                    <input type="text" onChange={this.changeEventPassword} value={this.state.password} required />
                    <input className="admin-login-submit" type="submit" value="Login" />
                </form>
                { this.state.loginError &&
                  <div className="admin-login-err">wrong email or password</div>
                }
            </div>  }
        </div>
         );
    }
}

export default Admin;

1 Ответ

0 голосов
/ 28 марта 2019

в классе Auth.js измените isAuthanticated на:

isAuthenticated() {
    //get token from local storage if there is one
    const jwttoken = localStorage.getItem('jwttoken');
    const bearer = 'Bearer ' + jwttoken;
    const data = new FormData();
    // get the website backend main url from .env
    const REACT_APP_URL = process.env.REACT_APP_URL
    fetch(`${REACT_APP_URL}/api/auth/verify`, {
        method: 'POST',
        headers: {
            'Accept': 'application/json',
            'Authorization': bearer,
        },
        body: data
    }).then(
        (response) => {
            response.json()
                .then((res) => {
                    if (response.status === 200) {
                        this.authenticated = true;
                    }
                    if (response.status === 401) {
                        localStorage.removeItem('jwttoken');
                        this.authenticated = false;
                    }
                })
        }
    ).catch((err) => {
        console.log(err)
    });
    return this.authenticated;
}

в PrivateRoute убедитесь, что вы вызываете Auth.isAuthanticated () таким образом, вы получаете значение true или false, основываясь на вызове fetch, который устанавливает для authenticated значение true или false и возвращает this.authenticated; вы делаете это правильно, просто проверьте орфографию

import React, { Component }  from  "react";
import { Route, Redirect, } from "react-router-dom";
import Auth from "./Auth"


export const PrivateRoute = ({ component: Component, ...rest }) => {
  return (
    <Route {...rest} render={(props) => (
      Auth.isAuthenticated() === true
        ? <Component {...props} />
        : <Redirect to='/admin' />
    )} />
      )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...