今天在调试 laravel passport 登录后,直接通过 Auth::guard('api')->user(),获取登录用户信息,返回 null。
看代码:
代理登录方法
public function login($mobile, $password)
{
if (auth()->attempt(['mobile' => $mobile, 'password' => $password])) {
return $this->proxy('password',
[
'username' => $mobile,
'password' => $password,
'scope' => '',
]);
}
return error(300, '登录失败!请确认您的用户名、密码');
}
public function proxy($grantType, array $data = [])
{
$data = array_merge($data, [
'client_id' => env('PASSPORT_CLIENT_ID'),
'client_secret' => env('PASSPORT_CLIENT_SECRET'),
'grant_type' => $grantType,
]);
// 这里的请求 url,不能是 '/oauth/token',会报错:
// cURL error 3: (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)
// 貌似是协议问题,生成的 url 不正确
// 解决方法:
// 1.完整的 url,例如:url('/oauth/token')
// 2.GuzzleHttp 公共配置:'base_uri' => 'http://xxx.com',
$response = $this->http->post(url('/oauth/token'), [
'form_params' => $data,
]);
$token = json_decode((string) $response->getBody(), true);
return $this->responseToken($token);
}
登录方法:
$username = $request->input('username');
$password = $request->input('password');
$proxy_response = $this->proxy->login($username, $password);
if($proxy_response['code'] != 200){
return response()->json($proxy_response);
}
// 执行到这里,说明已经登录成功
// 想在这里直接获取登录用户信息,所以,很自然的使用了:
$user = Auth::guard('api')->user();
dd($user); // 结果为 null
分析:
打印 $proxy_response,发现确实登录成功,并返回 acccess_token,登录肯定没问题
那可能的问题就是 Auth::guard('api')->user() 获取 user 的问题了。我们一般 api 正常的行为是
HTTP Authorization Bearer Token
而我们这里,没有走这个流程,从而导致了获取不到 user。(非常类似 cookie,必须等本次请求后,将 cookie 设置到浏览器,然后下一次才可以携带上)
验证:
查看 Auth::guard('api')->user() 源码
vendor/laravel/passport/src/Guards/TokenGuard.php
public function user(Request $request)
{
if ($request->bearerToken()) {
return $this->authenticateViaBearerToken($request);
} elseif ($request->cookie(Passport::cookie())) {
return $this->authenticateViaCookie($request);
}
}
public function bearerToken()
{
$header = $this->header('Authorization', '');
if (Str::startsWith($header, 'Bearer ')) {
return Str::substr($header, 7);
}
}
一看代码就有所发现,很明显的都是通过:
$request 来获取参数
在 header 中得到 Authorization,然后解析出来 Bearer,从而得到 token,来获取用户
我们上面调用时,$request 并没有 Authorization Bearer,所以返回 null
解决:
登录成功后,我们直接查询用户信息:
User::where('mobile', $mobile)->first();