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

Aks*_*ale 4 php jwt laravel-5

我在中间件中添加了以下代码,以使用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');
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是对于使用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');
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9iaXNzIjoiaHR0cDpcL1wvbG9jYWxob3N0OjgwMDFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNDcyNTI4NDU0LCJleHAiOjE0NzI1MzIwNTQsIm5iZiI6MTQ3MjUyODQ1NCwianRpIjoiM2E0M2ExYTZlNmM5NjUxZDgxYjZhNDcxMzkxODJlYjAifQ.CH8ES2ADTCrVWeIO8uU31bGDnH7h-ZVTWxrdXraLw8s"
Run Code Online (Sandbox Code Playgroud)

我能够看到有效令牌,该令牌正在用于访问其他路由,并且对于其他所有路由都正常运行。

提前致谢!!!

Ray*_*eng 5

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

在Tymon \ JWTAuth \ JWTAuth类的第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));
}
Run Code Online (Sandbox Code Playgroud)

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

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);
   }
}
Run Code Online (Sandbox Code Playgroud)

正确的标题是这样的:

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

以上是我可以为您提供的服务,希望它能帮助您解决所有问题。如果不是这样,您仍然可以从这两个函数进行调试。


Ter*_*nal 5

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

 $headers = apache_request_headers();
 $request->headers->set('Authorization', $headers['authorization']);
Run Code Online (Sandbox Code Playgroud)

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']);
            }
        }
Run Code Online (Sandbox Code Playgroud)