Как реализовать частный маршрут с токеном JWT в React

Я устанавливаю панель мониторинга только для авторизованного пользователя. Как я могу настроить свой интерфейс для доступа к частному маршруту с помощью jwt из бэкэнда?

Это внутренний процесс входа

const knex = require('../../../../database');
const path = require('path');
const jwt = require('jsonwebtoken');

function getUser(email, password) {
  return knex('admin_account')
    .select('email')
    .where({
      email,
      password
    }).first();
}

// app/models/user.js
const signin = async (req, res) => {
  try {
    const email = req.body.email;
    const password = req.body.password;
    if (!email || !password) {
      return res.status(400)
        .json({
          success: false,
          data: {
            error: "Email and password cannot be empty"
          },
        });
    }
    const result = await getUser(email, password)
    if (!result) {
      return res.status(404)
        .json({
          success: false,
          data: {
            error: "User tidak ditemukan, masukan Email dan Password-mu dengan benar"
          },
        });
    }
    return res.status(200).json({
      status: 'success',
      data: jwt.sign({
        role: 'admin',
        email
      }, process.env.SECRET)
    });
  } catch (error) {
    console.error({
      error: error.message
    });
    return res.status(400)
      .json({
        success: false,
        data: {
          error: JSON.stringify(error.message)
        },
      });
  }
}
module.exports = signin

А это интерфейс входа и приложения

class Login extends React.Component {
  state = initialState

  handleSubmit = input => {
    input.preventDefault();
    const formData = new FormData();

    if (this.formisValid(this.state)) {
      this.setState({ errors: [], loading: true });
      formData.set('email', this.state.email)
      formData.set('password', this.state.password)

      axios({
        method: 'POST',
        url: config.endpoint + '/api/v1/admin',
        data: formData,
        config: { headers: {'Content-Type': 'multipart/form-data' }}
      })
      .then( response => response.json())
      .then((response) => {
        if (!response.error) {
          this.setState({ 
            initialState,
            submit: true
          });
          this.setState({ loading: false});
          console.log('User Login', response)
          this.props.history.push('/admin/dashboard');
        }


      }).catch((errors) => {
        // ? Show to user that request is failed
        this.setState({ errors: [errors] })
        this.setState({ loading: false });
        console.log('User not found, login failed', errors)
      });
    }
  };

  handleInputError = (errors, inputName) => {
      ...
  };

  render() {
    ...

    return (
        ...
        );
  }
}

export default Login;
class App extends Component {

  render() {
    return (
      <Router>
        <div>
          {/*This is the function to Route to Page (via switch)*/}
          <Switch>
            <Route exact path="/" component={Home} />
            <Route exact path="/login/admin" component={Login} />
            ...
            <Route exact path="/admin/dashboard" component={Dashboard} />
          </Switch>
        </div>
      </Router>
    );
  }
}

Процесс входа проходит гладко, но я застрял в том, как сохранить токен и сделать маршрут приватным с помощью jwt

Большое спасибо, мой друг, спасибо за вашу помощь!


person Studentofcode    schedule 08.09.2019    source источник


Ответы (1)


Я не уверен, что понимаю ваш вопрос на 100%. Если я правильно понимаю, вы пытаетесь запретить некоторым пользователям доступ к определенной локации, если она не имеет токена (отключена).

В моем клиентском интерфейсе я использую контекст для управления токеном и обмена им между компонентами.

App.js будет выглядеть так.

const App = () => {
  return (
    <TokenProvider>
      <div className="App">
        <RouteComponent />
      </div>
    </TokenProvider>
  )
};

const RouteComponent = () => {
  const { token } = useContext(TokenContext);

  return (
    <>
      {token ? (
        <Switch>
          ...Private routes
        </Switch>
      ) : (
        <Switch>
          ...Public routes
        </Switch>
      )}
   </>
  )
};

Чтобы быть уверенным, что пользователь не получит доступ к недоступному местоположению, вы устанавливаете перенаправление на страницу входа в качестве примера.

Я надеюсь, что это может помочь вам, и я сожалею, если я сделал ошибку.

NB: Это основано на моем опыте, я не говорю, что это хороший способ сделать это, но в моем случае это решает проблему.

person CedFon    schedule 08.09.2019