Laravel 5.2 身份验证令牌
Laravel 5.2 Authentication Token
我正在尝试在 Laravel 5.2 中实施基于令牌的身份验证。我所做的是:
Routes.php
Route::group([
'middleware' => ['auth:api']
], function() {
Route::get('/api/reservation', 'apiController@get');
});
我修改了 User 模型并添加了 api_token
字段并通过 seeders
:[=23 添加了一个带有随机字符串的新用户=]
迁移
Schema::table('users', function (Blueprint $table) {
$table->string('api_token', 60)->unique()->nullable()->default(null);
});
播种机
User::create([
...,
'api_token' => str_random(60),
]);
控制器
class apiController extends Controller
{
function get(Request $request) {
return Reserva::all();
}
}
然后,在 Postman
中,我尝试 GET url 添加 /api/reservation?api_token=xxxxx
和我在数据库中的令牌,但我总是得到 Unauthorized.奇怪的是,如果我在身份验证中间件上执行 dd($this->auth)
,我会得到一个带有 name='web'
的 TokenGuard
对象。不应该是api
吗?
也许我误解了什么,你们能给我提示吗?谢谢
您正在使用的 auth:api
中间件使用 Laravel Passport。如果您想要基于自定义令牌的身份验证,就像您在创建自己的令牌时所做的那样,则不能使用它。
如果您想使用 Passport,请执行以下操作:
保持你的路线。需要身份验证的路由必须在 auth:api
中间件内。
您可以删除 users
table 的 api_token
字段。迁移中的 $table->rememberToken()
功能与你想到的 API 令牌完全不同。事实上,令牌根本不存储在数据库中。您在数据库 oauth_access_token
table 中看到的令牌不是您用于 HTTP 请求的令牌。
不要像您一样创建自定义令牌。检查 login/password 对用户是否有效,生成一个令牌并 return 它给 API 的消费者,像这样:
if (Auth::attempt(['login' => $req->login, 'password' => $req->password])) {
$user = Auth::user();
$token = $user->createToken('ToutelaBreizh')->accessToken;
return response()->json(['token' => $token],200);
}
注意将 login/register 路由放置在 auth:api
中间件之外,否则您需要向本应为您提供此令牌的路由提供令牌 - 这是没有意义的。
接下来,确保将令牌发送到请求的 Authorization
header 中的 API,而不是像您那样在请求参数中发送。在 Postman 中添加以下 header:
Authorization: Bearer your_token_retrieved_before
大功告成,可以将 API 与 Postman 一起使用了。
以防其他人遇到这个问题。我的问题是在 Authenticate
中间件中。我有一个旧版本。
我有这个 Authenticate
中间件:
class Authenticate
{
/**
* The Guard implementation.
*
* @var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* @param Guard $auth
* @return void
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('login');
}
}
return $next($request);
}
}
然后我通过更改它来解决它:
class Authenticate
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return rediresct()->guest('login');
}
}
return $next($request);
}
}
我正在尝试在 Laravel 5.2 中实施基于令牌的身份验证。我所做的是:
Routes.php
Route::group([
'middleware' => ['auth:api']
], function() {
Route::get('/api/reservation', 'apiController@get');
});
我修改了 User 模型并添加了 api_token
字段并通过 seeders
:[=23 添加了一个带有随机字符串的新用户=]
迁移
Schema::table('users', function (Blueprint $table) {
$table->string('api_token', 60)->unique()->nullable()->default(null);
});
播种机
User::create([
...,
'api_token' => str_random(60),
]);
控制器
class apiController extends Controller
{
function get(Request $request) {
return Reserva::all();
}
}
然后,在 Postman
中,我尝试 GET url 添加 /api/reservation?api_token=xxxxx
和我在数据库中的令牌,但我总是得到 Unauthorized.奇怪的是,如果我在身份验证中间件上执行 dd($this->auth)
,我会得到一个带有 name='web'
的 TokenGuard
对象。不应该是api
吗?
也许我误解了什么,你们能给我提示吗?谢谢
您正在使用的 auth:api
中间件使用 Laravel Passport。如果您想要基于自定义令牌的身份验证,就像您在创建自己的令牌时所做的那样,则不能使用它。
如果您想使用 Passport,请执行以下操作:
保持你的路线。需要身份验证的路由必须在 auth:api
中间件内。
您可以删除 users
table 的 api_token
字段。迁移中的 $table->rememberToken()
功能与你想到的 API 令牌完全不同。事实上,令牌根本不存储在数据库中。您在数据库 oauth_access_token
table 中看到的令牌不是您用于 HTTP 请求的令牌。
不要像您一样创建自定义令牌。检查 login/password 对用户是否有效,生成一个令牌并 return 它给 API 的消费者,像这样:
if (Auth::attempt(['login' => $req->login, 'password' => $req->password])) {
$user = Auth::user();
$token = $user->createToken('ToutelaBreizh')->accessToken;
return response()->json(['token' => $token],200);
}
注意将 login/register 路由放置在 auth:api
中间件之外,否则您需要向本应为您提供此令牌的路由提供令牌 - 这是没有意义的。
接下来,确保将令牌发送到请求的 Authorization
header 中的 API,而不是像您那样在请求参数中发送。在 Postman 中添加以下 header:
Authorization: Bearer your_token_retrieved_before
大功告成,可以将 API 与 Postman 一起使用了。
以防其他人遇到这个问题。我的问题是在 Authenticate
中间件中。我有一个旧版本。
我有这个 Authenticate
中间件:
class Authenticate
{
/**
* The Guard implementation.
*
* @var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* @param Guard $auth
* @return void
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('login');
}
}
return $next($request);
}
}
然后我通过更改它来解决它:
class Authenticate
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
if ($request->ajax() || $request->wantsJson()) {
return response('Unauthorized.', 401);
} else {
return rediresct()->guest('login');
}
}
return $next($request);
}
}