Как проверить, что данное значение является JWT в частном маршруте? - PullRequest
1 голос
/ 30 марта 2020

В настоящее время у меня есть следующий компонент React для частных маршрутов

    import { Route } from 'react-router-dom';
import React from 'react';
import { Redirect } from 'react-router';
import Cookies from 'js-cookie';
import jwtDecode from 'jwt-decode';
export default ({ component: Component, render: renderFn, authed, name, ...rest }) => {

  var decoded = [];
  decoded.permited = [];
  var accesstoken = Cookies.get('accesstoken');


    if((accesstoken)){
    var decoded  = jwtDecode(accesstoken)
    }

  return ( //Second case is for iframe based renders
    <Route {...rest} render={props => ((authed === true) && (decoded.permited.includes(name) === true)) ? renderFn(props) : <Redirect to={{ pathname: '/login', state: { from: props.location } }} />} />
  );

}

Он работает нормально, если нет кулинара ie с токеном, который он перенаправляет на логин. Если он есть, он оценивает ваши разрешения, включенные в токен, и на основе этого позволяет вам указать указанный c маршрут или номер.

Проблема возникает, когда я вставляю повара ie со случайным значением, для пример "undefined" или "thisisarandomstring". Когда я это делаю, функция

 if((accesstoken)){
var decoded  = jwtDecode(accesstoken)
}

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

Мне нужен способ проверить, что переданный аргумент является токеном доступа перед попыткой его декодировать. Или что-то в этом роде, чтобы не взломать sh.

Я пробовал что-то вроде этого

    export default ({ component: Component, render: renderFn, authed, name, ...rest }) => {

  var decoded = [];
  decoded.permited = [];
  var accesstoken = Cookies.get('accesstoken');

  console.log("first value")
  console.log(accesstoken)

 if(accesstoken === "undefined"){
  console.log("value after equaled string")
   accesstoken = undefined
   console.log(accesstoken)
 }
    if((accesstoken)){
      console.log("value in the decode")
    var decoded  = jwtDecode(accesstoken)
    }

  return ( //Second case is for iframe based renders
    <Route {...rest} render={props => ((authed === true) && (decoded.permited.includes(name) === true)) ? renderFn(props) : <Redirect to={{ pathname: '/login', state: { from: props.location } }} />} />
  );

}

Попытка принудительно установить значение в реальное неопределенное значение, если обнаруженная строка не определена, но в любом случае он будет обрабатывать sh, потому что по какой-то причине он все еще входит в этот декодер, если.

Я сделал такую ​​проверку, потому что мое приложение иногда устанавливает строку со значением "undefined" из-за некоторой неконтролируемой ошибки что я не могу найти в другом месте, поэтому я хотел управлять им из частного маршрута.

Но в любом случае, идеальным сценарием было бы проверить, имеет ли он формат jwt или что-то подобное, прежде чем пытаться декодировать это.

Есть идеи о том, что я мог сделать?

РЕДАКТИРОВАТЬ: Больше информации

Это действительно никогда не проходит мимо функции jwtDecode (), потому что возвращает ошибку

InvalidTokenError {сообщение: «Указан недопустимый токен: невозможно прочитать свойство« заменить »из неопределенного»} сообщение: «Указан недействительный токен: невозможно прочитать свойство« заменить »из unde оштрафован "

Так что я не совсем уверен, как с этим справиться, потому что приложение вылетает прямо там без возможности обработать что-либо

Ответы [ 2 ]

1 голос
/ 30 марта 2020

Если вам нужно перехватить неправильный токен до его передачи на jwtDecode, вы можете проверить структуру. JWT состоит из 3 частей, разделенных ., и первые две части являются объектами JSON в кодировке base64url и всегда начинаются с ey ( из-за кодирования { в base64). Вы можете проверить, имеет ли токен:

  1. 3 сегмента, разделенных . т.е. ..
  2. первые два сегмента начинаются с ey
  3. все 3 части имеют только символы в наборе символов base64url.

Это должно быть уверено, что это JWT. Конечно, нет никакой гарантии, что при тестировании с помощью «eyXXX.eyXXX.AB C» проверка проходит и декодирование по-прежнему не выполняется.

В простых случаях, когда jwtDecode возвращает null для недействительного токен (я использую пакет jsonswebtoken для node-js, и он действительно возвращает только null в этом случае), вы можете выполнить простую проверку на ноль:

var decoded  = jwtDecode(accesstoken)
if (decoded == null)
{
  console.log("not a valid token")
  // your error handling
}
else
  // continue with decoded token
0 голосов
/ 30 марта 2020
import { Route } from 'react-router-dom';
import React from 'react';
import { Redirect } from 'react-router';
import Cookies from 'js-cookie';
import jwtDecode from 'jwt-decode';
export default ({ component: Component, render: renderFn, authed, name, ...rest }) => {

  var decoded = [];
  decoded.permited = [];
  var accesstoken = Cookies.get('accesstoken');

  if ((accesstoken)) {
    try {
      var decoded = jwtDecode(accesstoken)
    } catch (err) {
     Cookies.remove('accesstoken')
    }

  }

  return ( //Second case is for iframe based renders
    <Route {...rest} render={props => ((authed === true) && (decoded.permited.includes(name) === true)) ? renderFn(props) : <Redirect to={{ pathname: '/login', state: { from: props.location } }} />} />
  );

}

Используя блок try catch, в улове я удалил повар ie, чтобы он не взломал sh приложение, поскольку, очевидно, это было одной из причин, по которой он был вызван, поскольку повар ie был оставлен там висеть

...