如何正确使用 Bearer 代币?

Posted

技术标签:

【中文标题】如何正确使用 Bearer 代币?【英文标题】:How to properly use Bearer tokens? 【发布时间】:2017-03-27 16:50:29 【问题描述】:

我正在php 中创建一个授权系统,我遇到了传递 JWT 令牌的承载方案,我阅读了 [RFC 6750][1]。我有以下疑问:

    这如何提高安全性? 成功授权和登录后,服务器在其正文中使用 JWT 令牌响应客户端,现在当客户端发出另一个请求时,我不清楚如何实际执行此操作,我想在授权中从客户端发送令牌请求中的标头,所以现在我应该将“Bearer”添加到我在上一个来自服务器的响应中收到的令牌之前,如果是,那么服务器在接收到 Authorization 标头时,应该只用空格分割字符串,然后取从获得的数组中提取第二个值,然后对其进行解码?例如Authorization: Bearer fdbghfbfgbjhg_something,服务器应该如何处理这个decodeFunc(explode(" ", $this->getRequest()->getHeader("Authorization"))[1])? [1]:https://www.rfc-editor.org/rfc/rfc6750

【问题讨论】:

【参考方案1】:

1.提高安全性,因为如果在url中发送的header中没有发送token,它将被网络系统记录,服务器日志......

2.一个很好的获取Bearer令牌的函数

/** 
 * Get header Authorization
 * */
function getAuthorizationHeader()
    $headers = null;
    if (isset($_SERVER['Authorization'])) 
        $headers = trim($_SERVER["Authorization"]);
    
    else if (isset($_SERVER['HTTP_AUTHORIZATION']))  //nginx or fast CGI
        $headers = trim($_SERVER["HTTP_AUTHORIZATION"]);
     elseif (function_exists('apache_request_headers')) 
        $requestHeaders = apache_request_headers();
        // Server-side fix for bug in old android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization)
        $requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders));
        //print_r($requestHeaders);
        if (isset($requestHeaders['Authorization'])) 
            $headers = trim($requestHeaders['Authorization']);
        
    
    return $headers;


/**
 * get access token from header
 * */
function getBearerToken() 
    $headers = getAuthorizationHeader();
    // HEADER: Get the access token from the header
    if (!empty($headers)) 
        if (preg_match('/Bearer\s(\S+)/', $headers, $matches)) 
            return $matches[1];
        
    
    return null;

【讨论】:

这是一个很好的函数,你已经建议了,但是我要返回的 $headers,它会说:Bearer <space> <AuthToken> 所以现在,只用空格分解字符串并取实际的令牌,还是完整的字符串 (Bearer <space> <token>) 应该被视为一个整体? <AuthToken> 没错。你可以按空间爆炸。 我错过了一个功能。 XD 能否添加setBearerToken函数?? 我只是使用 substr() 来获取实际的令牌,而不是承载者。应该比 preg_match() 快得多。【参考方案2】:

我建议使用以下 RegEx 来检查它是否是有效的 jwt 令牌:

/Bearer\s((.*)\.(.*)\.(.*))/

也可以通过matches[1]访问它。

这是一个 JWT-Token 的结构,见:https://jwt.io/

【讨论】:

Regex 并不总是推荐的解析字符串的方法,除非您无法使用现有的 PHP 字符串函数。 正则表达式用于查找模式。 Imo,您可以使用正则表达式来解析格式为“Bearer ”的 jwt 令牌。在令牌验证方面,我相信这是我能想到的最佳方法。接受的答案也使用正则表达式。我不知道为什么即使它有更好的正则表达式也会被否决。 这根本不是一个好方法。 JWT 令牌可以使用私有/公共证书进行签名,正则表达式不会检查。

以上是关于如何正确使用 Bearer 代币?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 UNISWAP API 获取代币价格

如何将 RSK 代币余额转换为 Javascript 数字?

如何在 Solana 中铸造限量版代币

如何正确处理标头中的 JWT

如何使用 web3.py 在钱包之间转移 ERC20 代币

在 cookie 中存储 Bearer 令牌的安全性