如何检查给定值是不是是私有路由中的 JWT?

Posted

技术标签:

【中文标题】如何检查给定值是不是是私有路由中的 JWT?【英文标题】:How to check that a given value is a JWT in a private route?如何检查给定值是否是私有路由中的 JWT? 【发布时间】:2020-07-10 12:46:02 【问题描述】:

目前我有以下用于私有路由的 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   /> />
  );


它工作正常,如果没有带有令牌的 cookie,它会重定向到登录。如果有,它会评估令牌中包含的您的权限,并据此让您输入特定路线或否。

当我插入一个带有随机值的 cookie 时,就会出现问题,例如 "undefined" 或 "thisisarandomstring"。当我这样做时,函数

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

一直执行,jwtDecode崩溃,所以应用崩溃。

在尝试解码之前,我需要一种方法来检查传递的参数是否是访问令牌。或者类似的东西让它不会崩溃。

我试过这样的东西

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


如果检测到的字符串未定义,则尝试将值强制为真正的未定义,但无论如何它都会崩溃,因为由于某种原因它仍然会进入该解码 if。

我做了同样的检查,因为我的应用有时会设置一个值为“未定义”的字符串,因为我似乎无法在其他地方找到一些不受控制的错误,所以我想从私有路由中控制它。

但无论如何,理想的情况是在尝试解码之前检查它是否具有 jwt 格式或类似的格式。

知道我能做什么吗?

编辑:更多信息

它真的永远不会超过 jwtDecode() 函数,因为它返回一个错误

InvalidTokenError message: "Invalid token specified: Cannot read property 'replace' of undefined" message: "InvalidToken specified: Cannot read property 'replace' of undefined"

所以我不太确定如何处理,因为应用程序在那里崩溃,无法处理任何事情

【问题讨论】:

在此处使用 try catch 块...如果令牌未定义或不是有效的 JWT,则会抛出错误,您可以在 catch 块中处理它。 @hussain.codes 成功了。 【参考方案1】:
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 块,在 catch 中我删除了 cookie,因此它不会使应用程序崩溃,因为显然这是导致它的原因之一,因为 cookie 挂在那里

【讨论】:

【参考方案2】:

如果您需要在传递给jwtDecode 之前捕获错误的令牌,您可以检查结构。 一个 JWT 由 3 部分组成,由 . 分隔,前两部分是 base64url 编码的 JSON 对象,始终以 ey (due to the base64 encoded ) 开头 所以你可以检查令牌:

    有 3 个段,由 . 分隔,即 .. 前两段以ey 开头 所有 3 个部分都只有 base64url 字符集中的字符。

这应该可以确定它是 JWT。当然不能保证,当你用“eyXXX.eyXXX.ABC”测试时,检查通过,解码仍然失败。

在简单的情况下,当 jwtDecode 为无效令牌返回 null 时(我在 node-js 上使用包 jsonswebtoken,在这种情况下它确实只返回 null) 你可以做一个简单的空检查:

var decoded  = jwtDecode(accesstoken)
if (decoded == null)

  console.log("not a valid token")
  // your error handling

else
  // continue with decoded token

【讨论】:

它在控制台InvalidTokenError message: "Invalid token specified: Cannot read property 'replace' of undefined" message: "Invalid token specified: Cannot read property 'replace' of undefined" 中返回错误。这意味着它永远不会到达那些 if 或 else 中的任何一个,因为它会在错误处停止。我试图创造某种承诺来解决这个问题,但到目前为止还没有运气 嘿,我终于用 try catch 块解决了它,在 catch 中我只是删除了 cookie,现在它可以正确重定向。但是感谢您的帮助

以上是关于如何检查给定值是不是是私有路由中的 JWT?的主要内容,如果未能解决你的问题,请参考以下文章

Nodejs + reactjs + jwt 检查

如何编写 R 脚本来检查直线;即,对于任何给定的行,一组列中的所有值是不是具有相同的值

node js jwt如何将令牌传递给其他路由以稍后检查登录的用户信息

Laravel 验证 - 如何检查给定数组中是不是存在值?

如何检查 JSON 中的值类型并决定是不是反序列化?

如何从标头中的cookie中获取特定元素