如何正确使用Bearer令牌?

60

我正在使用PHP制作授权系统,并遇到了通过Bearer方案传递JWT令牌的问题,我阅读了[RFC 6750][1]。我有以下疑问:

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

185

1.提高安全性,因为如果令牌未发送到头文件而是发送到URL中,则会被网络系统记录在服务器日志中....

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>的格式,那么现在,仅仅通过空格来分割字符串并获取实际的token是正确的吗?还是应该将整个字符串(Bearer <space> <token>)作为一个整体来处理? - Ashish Ranjan
我错过了一个函数。XD - Ngô Văn Thao
请问您能否添加 setBearerToken 函数? - Fayyaz Ali
4
我会使用substr()函数来获取实际令牌而不是Bearer。这应该比preg_match()函数快得多。 - InputOutput
@user4271704 请查看 getAuthorizationHeader 函数。认证令牌可以存储在 AuthorizationHTTP_AUTHORIZATIONapache_request_headers 函数中,具体取决于您的服务器版本。 - Ngô Văn Thao
显示剩余6条评论

4
我建议使用以下正则表达式来检查是否为有效的JWT令牌:

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

你可以使用 matches[1] 来访问它。

这是JWT令牌的结构,请参见:https://jwt.io/


1
正则表达式并不总是推荐的字符串解析方法,除非你无法通过现有的PHP字符串函数实现。 - sk8terboi87 ツ
5
正则表达式用于查找模式。我认为,您可以使用正则表达式解析格式为“Bearer <token>”的jwt令牌。在令牌验证方面,我认为这是我能想到的最佳方法。被接受的答案也使用了正则表达式。即使它具有更好的正则表达式,但我不知道为什么它会被投票反对。 - Arvind
2
这绝不是一个好的方法。JWT令牌可以使用私钥/公钥证书进行签名,而正则表达式无法对其进行检查。 - sridesmet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接