Laravel - JWT Auth 无法从请求中解析令牌

Posted

技术标签:

【中文标题】Laravel - JWT Auth 无法从请求中解析令牌【英文标题】:Laravel - JWT Auth The token could not be parsed from the request 【发布时间】:2017-01-06 05:21:09 【问题描述】:

我在中间件中添加了以下代码,用于使用JWT Auth 进行用户身份验证,这对于中间件处理的所有路由都适用。

public function handle($request, Closure $next)

    if ($request->has('token')) 
        try 
            $this->auth = JWTAuth::parseToken()->authenticate();
            return $next($request);
         catch (JWTException $e) 
            return redirect()->guest('user/login');
        
    

但是对于带有 Post Method 的一条路线,令牌正确传递但我仍然得到:

JWTException - 无法从请求中解析令牌

我尝试时在同一条路线上:

public function handle($request, Closure $next)

    if ($request->has('token')) 
        try 
            dd($request->input('token'));
            $this->auth = JWTAuth::parseToken()->authenticate();
            return $next($request);
         catch (JWTException $e) 
            return redirect()->guest('user/login');
        
    

输出:

"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9iaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwMDFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNDcyNTI4NDU0LCJleHAiOjE0NzI1MzIwNTQsIm5iZiI6MTQ3MjUyODQ1NCwianRpIjoiM2E0M2ExYTZlNmM5NjUxZDgxYjZhNDcxMzkxODJlYjAifQ.CH8ES2ADTCrVWeIO8uU31bGDnH7h-ZVTWxrdXraLw8s"

我能够看到我用来访问其他路由的有效令牌,并且它在所有其他路由上都可以正常工作。

提前致谢!!!

【问题讨论】:

【参考方案1】:

根据您的描述,我检查了 JWT Auth 的源文件。

Tymon\JWTAuth\JWTAuth line 191 - 219 类中,有两个函数:

/**
 * Parse the token from the request.
 *
 * @param string $query
 *
 * @return JWTAuth
 */
public function parseToken($method = 'bearer', $header = 'authorization', $query = 'token')

    if (! $token = $this->parseAuthHeader($header, $method)) 
        if (! $token = $this->request->query($query, false)) 
            throw new JWTException('The token could not be parsed from the request', 400);
        
    

    return $this->setToken($token);


/**
 * Parse token from the authorization header.
 *
 * @param string $header
 * @param string $method
 *
 * @return false|string
 */
protected function parseAuthHeader($header = 'authorization', $method = 'bearer')

    $header = $this->request->headers->get($header);

    if (! starts_with(strtolower($header), $method)) 
        return false;
    

    return trim(str_ireplace($method, '', $header));

检查它们的逻辑,我认为您的请求标头没有正确提供。

if (! $token = $this->parseAuthHeader($header, $method))  // all your get method not passed this step
   if (! $token = $this->request->query($query, false))  // all your post method stucked here 
       throw new JWTException('The token could not be parsed from the request', 400);
   

格式正确的标题如下所示:

http POST http://$host/api/v1/product/favorite/111 "Authorization: Bearer $token"

这就是我能提供给你的全部内容,希望它能帮助你解决你的想法。如果不是,您仍然可以调试这两个函数。

【讨论】:

@akshaykhale,希望这对您有所帮助。如果是这样,请接受我的回答。这样我们都可以获得声誉 是的,您的回答很有帮助,JWTAuth 文件无法从请求中读取令牌。感谢您的帮助。【参考方案2】:

我在 ec2 amazon AMI Linux php7.2 apache2.4 上遇到了同样的问题,但令牌在 apache 请求标头中生成,但在 Laravel 请求标头中不可见 所以在中间件中添加这段代码,这将只适用于您的服务器,但可能不适用于 localhost。

 $headers = apache_request_headers();
 $request->headers->set('Authorization', $headers['authorization']);

JWT 中间件

    try 
            $headers = apache_request_headers(); //get header
            $request->headers->set('Authorization', $headers['authorization']);// set header in request

            $user = JWTAuth::parseToken()->authenticate();
         catch (Exception $e) 
            if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenInvalidException)
                return response()->json(['status' => 'Token is Invalid']);
            else if ($e instanceof \Tymon\JWTAuth\Exceptions\TokenExpiredException)
                return response()->json(['status' => 'Token is Expired']);
            else
                return response()->json(['status' => 'Authorization Token not found']);
            
        

【讨论】:

非常感谢您的帮助。这个解决方案对我有用,只是为了让它更准确:在我的情况下,我在这个 $headers['Authorization'] 数组中获取身份验证令牌。【参考方案3】:

我在/etc/apache2/apache2.conf 中添加了这个。

<Directory /var/www/html>
        AllowOverride all
</Directory>

(记得重启你的apache)

从我的网址中删除index.php,解决此问题。

/public/index.php/api/user/login -> /public/api/user/login

【讨论】:

【参考方案4】:

通过将RewriteRule ^ - [E=HTTP_AUTHORIZATION:%HTTP:Authorization] 添加到.htaccess 来修复它,因此授权标头不会被 Laravel 丢弃。将其添加到文档中可能很有用。

【讨论】:

请不要添加same answer to multiple questions。一旦您获得足够的声誉,就回答最好的一个并将其余的标记为重复项。如果不是重复的,请根据问题调整帖子并标记以取消删除。【参考方案5】:

我遇到了一个问题,并通过添加以下行获得了解决方案 .htaccess


RewriteRule ^ - [E=HTTP_AUTHORIZATION:%HTTP:Authorization]

【讨论】:

以上是关于Laravel - JWT Auth 无法从请求中解析令牌的主要内容,如果未能解决你的问题,请参考以下文章

tymon/jwt-auth Laravel:无法验证令牌签名

Laravel / Lumen Auth JWT令牌在后续请求中无效,是否可能已过期?

Laravel/Lumen Auth JWT 令牌在后续请求中无效,它可能已过期吗?

Auth0 Laravel 获取 JWT 令牌

laravel composer install 无法解决 tymon/jwt-auth 的可安装包

使用带有 JWT Auth/Laravel 的 Angular JS 获取新的刷新令牌后,如何恢复/重新发送请求?