【问题标题】:How to extract token string from Bearer token?如何从承载令牌中提取令牌字符串?
【发布时间】:2018-10-21 10:18:17
【问题描述】:

例如,我在标头中有以下 Bearer JWT,那么提取令牌本身的优雅方法是什么?基本上是Bearer 之后的任何内容。由于这可能是其他格式,我不想假设它总是以Bearer 开头。我用的是node-jsonwebtoken,没找到这样的方法。

Authorization: Bearer eyJhbGciOiJIUzI1NiIXVCJ9...TJVA95OrM7E20RMHrHDcEfxjoYZgeFONFh7HgQ

【问题讨论】:

    标签: node.js jwt


    【解决方案1】:

    你可以使用空格分割

    TokenArray = jwttoken.split(" ");
    

    它将以数组形式存储,其中第二个索引(第一个索引为 1 为 0)TokenArray[1] 将是令牌并使用

    Jwt.decode(TokenArray[1])
    

    解码令牌 JWT 是一种令牌标准,您可以在许多标准中使用,其中最常用的情况之一是用于授权,它也可以通过多种方式完成,但首选的标准方式是在不记名授权标头中发送它 您可以使用refresh_token 代替bearer token,但您必须将令牌存储在某处,这会以某种方式降低术语stateless token 的效率。所以承载方法是完全无状态的并且是首选方法

    【讨论】:

    • 请小心解码,因为它不会验证令牌是否有效,请改用验证,如果无效则处理拒绝
    【解决方案2】:

    出于安全原因,您应该确保 Authorization 标头具有预期的内容。如果您期望它,您根本不应该接受不以Bearer 开头的标头(“Bearer”是 RFC 中的建议,它不是强制性的)“。

    if (authHeader.startsWith("Bearer ")){
         token = authHeader.substring(7, authHeader.length);
    } else {
       //Error
    }
    

    【讨论】:

    【解决方案3】:

    我编写了一个从请求标头或查询中提取令牌的函数。我把它贴在这里。希望它可以帮助某人。

    function extractToken (req) {
        if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
            return req.headers.authorization.split(' ')[1];
        } else if (req.query && req.query.token) {
            return req.query.token;
        }
        return null;
    }
    

    【讨论】:

    • 你调用 split() 两次,效率低。
    • @hirikarate 它比声明一个变量来存储拆分结果更有效。
    • @Sinandro 取决于你在说什么。表面上它的内存效率更高,但这取决于 .split 的编写方式。这绝对不是更节省时间。
    【解决方案4】:

    如果您收到此错误 spring boot rest 应用程序,您可以尝试以下示例:

    可能你发布了你的令牌 => "Authorization" :"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJqYXZhaW51c2UiLCJleHAiOjE1Njc3ODkxOTcsImlhdCI6MTU2Nzc3MTE5N30.PQZQ4q4orAUs-vScyJVguIlVC0BloTbmqz_i7d36Ij9kBZrdAfkyI9iy_8Roh6TaMS8hfzjz-lDUsQnSt1OD4g"

    所以您将“Bearer [space]”字符串添加到您的令牌字符串 样本 : "Authorization" :"Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJqYXZhaW51c2UiLCJleHAiOjE1Njc3ODkxOTcsImlhdCI6MTU2Nzc3MTE5N30.PQZQ4q4orAUs-vScyJVguIlVC0BloTbmqz_i7d36Ij9kBZrdAfkyI9iy_8Roh6TaMS8hfzjz-lDUsQnSt1OD4g"

    【讨论】:

      【解决方案5】:

      我想出的最通用的解决方案(您可以根据需要调整“针”):

      const authHeader = 'Bearer mytokengoeshere OtherThing...';
      const needle = 'Bearer ';
      const bearerAt = authHeader.indexOf(needle);
      const spaceAfterTokenAt = authHeader.indexOf(' ', needle.length);
      const token = authHeader.slice(
          bearerAt + needle.length,
          spaceAfterTokenAt > -1 ? spaceAfterTokenAt : authHeader.length
      );
      

      如果您确定授权标头与“Bearer mytokengoeshere”字符串一样简单,则可以完全删除 spaceAfterTokenAt 逻辑。

      【讨论】:

        【解决方案6】:

        对于 typescript、nodejs,导入 jwt-decode

        import jwtDecode from 'jwt-decode';
        
            const authHeader = String(req.headers['authorization'] || '');
            if (authHeader.startsWith('Bearer ')) {
              const token = authHeader.substring(7, authHeader.length);
              const payload = jwtDecode(token) as JwtPayload;
            }
        

        JwtPayload 是一个接口或一个类。

        export interface JwtPayload {
          id: string;
          username: string;
          email: string;
          role: string;
          expire: number;
        }
        

        【讨论】:

          【解决方案7】:

          返回令牌的简单实用函数

          function getToken(req) {
            if (
              req.headers.authorization &&
              req.headers.authorization.split(" ")[0] === "Bearer"
            ) {
              return req.headers.authorization.split(" ")[1];
            } 
            return null;
          }
          

          然后可以将令牌传递给其他方法。比如验证签名。

          
            const token = getToken(req);
          
            if (!token) {
              throw new Error("Authorization token is required");
            } 
           jwt.verify(token, secret, function (err, decoded) {
              if (err) {
                throw new Error("Error : " + err);
              }
              console.log(decoded);
            });
          

          【讨论】:

            【解决方案8】:

            你可以在 TypeScript 中做这样的事情,这比我在这里看到的大多数答案都干净。

            export const parseBearer = (bearer: string) => {
              const [_, token] = bearer.trim().split(" ");
              return token;
            };
            

            基本上是截断不记名字符串,按空格分割,然后在索引为 1 处获取元素(令牌)。

            要处理令牌,您所要做的就是使用诸如jsonwebtoken 之类的包来验证它。最终结果将如下所示:

            import jwt from "jsonwebtoken"
            
            const authorizationHeader = req.headers["Authorization"];
            const token = parseBearer(authorizationHeader);
            
            try {
                const decoded = jwt.verify(token, secret);
                return res.json(decoded);
            } catch (error: any) {
                return res.status(403).json({ error: "Invalid token" });
            }
            

            【讨论】:

              【解决方案9】:

              //当token是String时,我看到字符串之前和结尾都有“,所以我必须从token中删除”,如下所示 // 添加带有 AccessToken 的 Authorization 标头。

                          token = token.Substring(1, token.Length-2);
                              client.DefaultRequestHeaders.Authorization =  new AuthenticationHeaderValue("Bearer", token);
                            
              

              【讨论】:

                【解决方案10】:

                这是我为 typescript 解析承载的安全和干净代码的版本。

                        // parse token bearer
                        const tokenBearer = req?.headers?.authorization ? (() => {
                            const authHeader = <string>req?.headers?.authorization || ``
                            const [code,token] = authHeader.trim().split(` `)
                            if (code !== `Bearer`)
                                return void 0
                            else
                                return token
                        })() : void 0
                

                【讨论】:

                  【解决方案11】:

                  bearerToken.split(" ")[1]

                  【讨论】:

                  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
                  猜你喜欢
                  • 1970-01-01
                  • 2019-09-28
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-12-01
                  • 2018-06-11
                  • 2018-11-14
                  • 1970-01-01
                  相关资源
                  最近更新 更多