我正在使用我的API设置身份验证路由。 我正在使用带有tymondesigns / jwt-auth 1.0.0-rc.1的laravel 5.5和Postman来与API进行交互。
认证路由/方法似乎有效:
/**
* 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'));
}
Postman 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',
],
];
由于
答案 0 :(得分: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'
]]);
});
因此,在您的情况下,保留源文件\ vendor \ tymon \ jwt-auth \ src \ JWTAuth.php,并在您的自定义类中编写如下代码。
/**
* 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);
}
答案 1 :(得分: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';
});
]):
答案 2 :(得分:0)
答案是:&#34;这与当前状态下的此功能不兼容而不自行扩展#34;。
我希望这可以帮助其他人使用UUID作为主键。您无法在不编辑供应商项目或扩展的情况下执行此操作......但是,这是一个简单的解决方法。
我将与软件包作者一起提出这个问题,并希望找到一个更持久的解决方案。但是,这是一个解决方法:
背景:
id
列。 id_text
字段作为自动生成的mysql字段存在JWT中的问题:
在档案\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'
会回避这个问题......事实证明它并没有。我将把这个反馈给作者
修改核心只是一个练习......我很确定这个课程可以扩展,我很快就会尝试这个。在大多数情况下,编辑源当然是次优的。
但是 - 我希望这种挖掘可以帮助人们理解这个问题。