今天在調試 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();