【问题标题】:Laravel - JWT Auth The token could not be parsed from the requestLaravel - JWT Auth 无法从请求中解析令牌
【发布时间】: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"

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

提前致谢!!!

【问题讨论】:

    标签: php laravel-5 jwt


    【解决方案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}]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-02-28
        • 2019-01-14
        • 1970-01-01
        • 2021-10-18
        • 2016-02-19
        • 2016-10-20
        • 2023-03-28
        • 2020-05-11
        相关资源
        最近更新 更多