2017-10-18 66 views
0

我正在使用API​​设置认证路由。 我正在用tymondesigns/jwt-auth 1.0.0-rc.1和Postman与API进行交互使用laravel 5.5。Laravel tymondesigns/jwt-auth问题

认证途径/方法似乎工作:

/** 
* Authenticates a json request, generating a token. 
* 
* @param Request $request 
* @return JsonResponse 
*/ 
public function authenticate(Request $request) 
{ 
    // grab credentials from the request 
    $credentials = $request->only('email', 'password'); 

    try { 
     // attempt to verify the credentials and create a token for the user 
     if (! $token = JWTAuth::attempt($credentials)) { 
      return response()->json(
       [ 
        'error' => 'Invalid credentials.', 
        'detail' => 'Please use your email and password to generate a token.' 
       ], 
       401); 
     } 
    } catch (JWTException $e) { 
     // something went wrong whilst attempting to encode the token 
     return response()->json(
      [ 
       'error' => 'Could not create token', 
       'detail' => 'There was an internal problem and your token could not be created.' 
      ], 500 
     ); 
    } 

    // all good so return the token 
    return response()->json(compact('token')); 
} 

邮递员API POST请求返回(似乎是)一个有效的响应,例如:

{ 
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vc29sZGVyc3RhcmFwaS5jb20ubG9jYWwvYXBpL2F1dGhlbnRpY2F0ZSIsImlhdCI6MTUwNzg4NjU2OSwiZXhwIjoxNTA3ODkwMTY5LCJuYmYiOjE1MDc4ODY1NjksImp0aSI6IkpFWjBkc0dNbEVydXRHcFciLCJzdWIiOiIwNzk2MjhDMC03QjBDLTExRTYtODRERC1DQjAzMzVGN0JBNUQiLCJwcnYiOiI4N2UwYWYxZWY5ZmQxNTgxMmZkZWM5NzE1M2ExNGUwYjA0NzU0NmFhIn0.Dl2EEaYZx3H5XXG9WUcPXYKuma0ZjCvcCsb99hgB6O4" 
} 

首先,对于基本的测试目的,我用GET提供这个动作,使用下面的后缀:

?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vc29sZGVyc3RhcmFwaS5jb20ubG9jYWwvYXBpL2F1dGhlbnRpY2F0ZSIsImlhdCI6MTUwNzg4NjU2OSwiZXhwIjoxNTA3ODkwMTY5LCJuYmYiOjE1MDc4ODY1NjksImp0aSI6IkpFWjBkc0dNbEVydXRHcFciLCJzdWIiOiIwNzk2MjhDMC03QjBDLTExRTYtODRERC1DQjAzMzVGN0JBNUQiLCJwcnYiOiI4N2UwYWYxZWY5ZmQxNTgxMmZkZWM5NzE1M2ExNGUwYjA0NzU0NmFhIn0.Dl2EEaYZx3H5XXG9WUcPXYKuma0ZjCvcCsb99hgB6O4

为了验证这一点,如果我做到以下几点:

public function globalObjects(Request $request): JsonResponse { 
    var_dump(JWTAuth::parseToken()->authenticate(), JWTAuth::getToken()); exit; 

    // ... later code that never gets reached 
} 

我得到如下:

bool(false) object(Tymon\JWTAuth\Token)#809 (1) { ["value":"Tymon\JWTAuth\Token":private]=> string(384) "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOi8vc29sZGVyc3RhcmFwaS5jb20ubG9jYWwvYXBpL2F1dGhlbnRpY2F0ZSIsImlhdCI6MTUwNzg4NjU2OSwiZXhwIjoxNTA3ODkwMTY5LCJuYmYiOjE1MDc4ODY1NjksImp0aSI6IkpFWjBkc0dNbEVydXRHcFciLCJzdWIiOiIwNzk2MjhDMC03QjBDLTExRTYtODRERC1DQjAzMzVGN0JBNUQiLCJwcnYiOiI4N2UwYWYxZWY5ZmQxNTgxMmZkZWM5NzE1M2ExNGUwYjA0NzU0NmFhIn0.Dl2EEaYZx3H5XXG9WUcPXYKuma0ZjCvcCsb99hgB6O4" } 

..如:

  • 我收到令牌
  • 它没有找到用户
注意个

项目:

  • 我的主键是id,但它是一个UUID,所以二进制(16)...,因此:
  • 我设置的标识是:“标识” => '电子邮件'

以下请求:这里是\config\jwt.php

return [ 
    'secret' => env('JWT_SECRET', 'AqAWUTYISA56lrl2vcRtZQn4M4zk9onl'), 
    'ttl' => 60, 
    'refresh_ttl' => 20160, 
    'algo' => 'HS256', 
    'user' => 'App\User', 
    'identifier' => 'email', 
    'required_claims' => ['iss', 'iat', 'exp', 'nbf', 'sub', 'jti'], 
    'blacklist_enabled' => env('JWT_BLACKLIST_ENABLED', true), 
    'providers' => [ 
     'user' => 'Tymon\JWTAuth\Providers\User\EloquentUserAdapter', 
     'jwt' => 'Tymon\JWTAuth\Providers\JWT\Namshi', 
     'auth' => 'Tymon\JWTAuth\Providers\Auth\Illuminate', 
     'storage' => 'Tymon\JWTAuth\Providers\Storage\Illuminate', 

    ], 

]; 

感谢

+2

用部首 – Mohammad

+1

发送令牌@mohammad正在通过GET发送的令牌。令牌正在处理中。你可以在'Tymon \ JWTAuth \ Token'对象的var_dump中看到它。 – elb98rm

+0

请添加您的JWT配置文件。 – Camilo

回答

0

您接收到令牌但未正确解析您需要检查令牌解析成功。

if (! $auth = JWTAuth::parseToken();) { 
    throw Exception('JWTAuth unable to parse token from request'); 
} 
dd(\Auth::id()); 

我建议你去你的kernal.php和保护$ routeMiddleware阵列添加以下行

'jwt.auth' => 'Tymon\JWTAuth\Middleware\GetUserFromToken', 
'jwt.refresh' => 'Tymon\JWTAuth\Middleware\RefreshToken', 

然后转到您的路线和使用它像中间件这样

Route::group(['middleware' => 'jwt.auth'], function() { 
    // Your routes here that you want to protect 
     Route::get('foo', function() { 
     return 'Hello World'; 
      }); 
    ]): 
认证

enter image description here

+0

令牌解析正确(没有例外); dd()(或var_dump())的结果是'null'。感谢有关中间件的建议,我打算这么做,但现在我只想得到一个可以工作的动作*。 – elb98rm

0

答案是:“这不是对应的这个功能在它现在的状态下不会自动扩展“。

我希望这可以帮助任何其他人使用UUID作为主键。没有编辑供应商项目或扩展......你不能这样做。但是,这是一个简单的解决方案。

我将与软件包作者一起提出这个问题,并希望找到一个更持久的解决方案。然而,这里是一种解决方法:

背景:

  • 的UUID被存储在数据库中的二进制(16)id列。
  • 这不是人类可读/文字友好的。
  • 为了解决这个问题,id_text领域的自动生成的MySQL的领域存在
  • 音符 - 你永远不应该寻找使用这些(它强调的分贝严重)
  • 这些文本阅读,因而..可以很容易地使用形式等
  • 我创建了一个UuidHelper,以便容易翻译JWT

问题:

  • 钍Ë认证功能尝试将id_text作为ID
  • 显然解码,这总是失败

在文件\vendor\tymon\jwt-auth\src\JWTAuth.php

/** 
* Authenticate a user via a token. 
* 
* @return \Tymon\JWTAuth\Contracts\JWTSubject|false 
*/ 
public function authenticate() 
{ 
    $id_text = $this->getPayload()->get('sub'); 

    $uuid_helper = new UuidHelper(); 
    $id = $uuid_helper->textIdToId($id_text); 

    if (! $this->auth->byId($id)) { 
     return false; 
    } 

    return $this->user(); 
} 

不清晰的,所以我认为'identifier' => 'email'的文档会回避这个问题问题......事实并非如此。我将把这篇文章反馈给作者

修改核心只是一个练习......我很确定这个类可以扩展,我很快就会尝试。编辑源代码当然是次优的大多数情况。

但是 - 我希望这种挖掘能帮助人们理解这个问题。

2

下面是我在我的API中使用的解决方案非常好。

首先重写类Tymon\JWTAuth\Providers\Auth\Illuminate::class

<?php 


namespace Scryba\Code\Laravel\Providers\Auth\Jwt; 

use Tymon\JWTAuth\Contracts\Providers\Auth; 
use Illuminate\Contracts\Auth\Guard as GuardContract; 

class Illuminate implements Auth 
{ 
/** 
* The authentication guard. 
* 
* @var \Illuminate\Contracts\Auth\Guard 
*/ 
protected $auth; 

/** 
* Constructor. 
* 
* @param \Illuminate\Contracts\Auth\Guard $auth 
* 
* @return void 
*/ 
public function __construct(GuardContract $auth) 
{ 
    $this->auth = $auth; 
} 

/** 
* Check a user's credentials. 
* 
* @param array $credentials 
* 
* @return bool 
*/ 
public function byCredentials(array $credentials) 
{ 
    return $this->auth->once($credentials); 
} 

/** 
* Authenticate a user via the id. 
* 
* @param mixed $id 
* 
* @return bool 
*/ 
public function byId($id) 
{ 
    //you can see i added hex2bin($id)because i save my UUID primary key as 
    //binary(16) 
    return $this->auth->onceUsingId(hex2bin($id)); 
} 

/** 
* Get the currently authenticated user. 
* 
* @return mixed 
*/ 
public function user() 
{ 
    return $this->auth->user(); 
} 
} 

然后更新\config\jwt.php文件

'providers' => [ 

    /* 
    |-------------------------------------------------------------------------- 
    | JWT Provider 
    |-------------------------------------------------------------------------- 
    | 
    | Specify the provider that is used to create and decode the tokens. 
    | 
    */ 

    'jwt' => Tymon\JWTAuth\Providers\JWT\Namshi::class, 

    /* 
    |-------------------------------------------------------------------------- 
    | Authentication Provider 
    |-------------------------------------------------------------------------- 
    | 
    | Specify the provider that is used to authenticate users. 
    | 
    */ 

    //'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class, 
    'auth' => Scryba\Code\Laravel\Providers\Auth\Jwt\Illuminate::class, 

    /* 
    |-------------------------------------------------------------------------- 
    | Storage Provider 
    |-------------------------------------------------------------------------- 
    | 
    | Specify the provider that is used to store tokens in the blacklist. 
    | 
    */ 

    'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class, 

], 

在我的路线文件

////// Protected methods (requires Authenticatication) 
     $api->group(
      [ 
       'middleware' => ['api.auth'], 
       'providers' => ['jwt'], 

      ],function($api){ 

     $api->resource('cars', 'CarController', ['only' => [ 
      'index' ,'show' 
     ]]); 

     }); 

所以你的情况离开源文件\供应商\ tymon \ jwt-auth \ src \ JWTAuth.php,并将你的代码编写为belo如果适用,请在您的自定义类中输入

/** 
* Authenticate a user via the id. 
* 
* @param mixed $id 
* 
* @return bool 
*/ 
public function byId($id) 
{ 
    $id_text = $this->getPayload()->get('sub'); 

    $uuid_helper = new UuidHelper(); 
    $id = $uuid_helper->textIdToId($id_text); 

    return $this->auth->onceUsingId($id); 
}