摘要:看到社區常有人問用于密碼驗證方式來獲取的問題,剛好我最近一個項目使用,也是使用的密碼授權來做驗證,對于如何做登錄登出,以及多賬號系統的認證等常用場景做一下簡單的使用小總結。
看到Laravel-China社區常有人問Laravel Passport用于密碼驗證方式來獲取Token的問題,剛好我最近一個API項目使用Laravel Dingo Api+Passport,也是使用Oauth2 的"grant_type" => "password"密碼授權來做Auth驗證,對于如何做登錄登出,以及多賬號系統的認證等常用場景做一下簡單的使用小總結。
基本配置基本安裝配置主要參照官方文檔,具體不詳細說,列出關鍵代碼段
config/auth.php
"guards" => [ "api" => [ "driver" => "passport", "provider" => "users", ], ], "providers" => [ "users" => [ "driver" => "eloquent", "model" => AppModelsUser::class ], ],
Providers/AuthServiceProvider.php
public function boot() { $this->registerPolicies(); //默認令牌發放的有效期是永久 //Passport::tokensExpireIn(Carbon::now()->addDays(2)); //Passport::refreshTokensExpireIn(Carbon::now()->addDays(4)); Passport::routes(function (RouteRegistrar $router) { //對于密碼授權的方式只要這幾個路由就可以了 config(["auth.guards.api.provider" => "users"]); $router->forAccessTokens(); }); }
Middleware/AuthenticateApi.php 自定義中間件返回
auth->guard("api")->check()) { return $this->auth->shouldUse("api"); } throw new UnauthorizedHttpException("", "Unauthenticated"); } }
App/Http/Kernel.php
/** * The application"s route middleware. * * These middleware may be assigned to groups or used individually. * * @var array */ protected $routeMiddleware = [ "api-auth" => AuthenticateApi::class, ...... ]; }賬號驗證字段不止郵箱
對于賬號驗證不止是數據表中的emial字段,還可能是用戶名或者手機號字段只需要在User模型中添加findForPassport方法,示例代碼如下:
AppModelsUsers
class User extends Authenticatable implements Transformable { use TransformableTrait, HasApiTokens, SoftDeletes; public function findForPassport($login) { return $this->orWhere("email", $login)->orWhere("phone", $login)->first(); } }客戶端獲取access_token請求只傳用戶名和密碼
對于密碼授權的方式需要提交的參數如下:
$response = $http->post("http://your-app.com/oauth/token", [ "form_params" => [ "grant_type" => "password", "client_id" => "client-id", "client_secret" => "client-secret", "username" => "taylor@laravel.com", "password" => "my-password", "scope" => "", ], ]);
但是客戶端請求的時候不想把grant_type,client_id,client_secret,scope放到請求參數中或者暴露給客戶端,只像JWT一樣只發送username和password 怎么辦?很簡單我們只要將不需要請求的放到配置文件中,然后客戶端請求用戶名密碼以后我們再向oauth/token發送請求帶上相關的配置就可以了。
.env.php
OAUTH_GRANT_TYPE=password OAUTH_CLIENT_ID=1 OAUTH_CLIENT_SECRET=EvE4UPGc25TjXwv9Lmk432lpp7Uzb8G4fNJsyJ83 OAUTH_SCOPE=*
config/passport.php 當然該配置你可以配置多個client
return [ "grant_type" => env("OAUTH_GRANT_TYPE"), "client_id" => env("OAUTH_CLIENT_ID"), "client_secret" => env("OAUTH_CLIENT_SECRET"), "scope" => env("OAUTH_SCOPE", "*"), ];
LoginController.php的示例代碼如下,因為用了Dingo Api配置了api前綴,所以請求/api/oauth/token
/** * 獲取登錄TOKEN * @param LoginRequest $request * @return IlluminateHttpJsonResponse */ public function token(LoginRequest $request) { $username = $request->get("username"); $user = User::orWhere("email", $username)->orWhere("phone", $username)->first(); if ($user && ($user->status == 0)) { throw new UnauthorizedHttpException("", "賬號已被禁用"); } $client = new Client(); try { $request = $client->request("POST", request()->root() . "/api/oauth/token", [ "form_params" => config("passport") + $request->only(array_keys($request->rules())) ]); } catch (RequestException $e) { throw new UnauthorizedHttpException("", "賬號驗證失敗"); } if ($request->getStatusCode() == 401) { throw new UnauthorizedHttpException("", "賬號驗證失敗"); } return response()->json($request->getBody()->getContents()); }退出登錄并清除Token
對于客戶端退出后并清除記錄在oauth_access_tokens表中的記錄,示例代碼如下:
/** * 退出登錄 */ public function logout() { if (Auth::guard("api")->check()) { Auth::guard("api")->user()->token()->delete(); } return response()->json(["message" => "登出成功", "status_code" => 200, "data" => null]); }根據用戶ID認證用戶
app("auth")->guard("api")->setUser(User::find($userId));多用戶表(多Auth)認證
比如針對客戶表和管理員表分別做Auth認證的情況,也列出關鍵代碼段:
"guards" => [ "api" => [ "driver" => "passport", "provider" => "users", ], "admin_api" => [ "driver" => "passport", "provider" => "admin_users", ], ], "providers" => [ "users" => [ "driver" => "eloquent", "model" => AppModelsUser::class ], "admin_users" => [ "driver" => "eloquent", "model" => AppModelsAdminUser::class ], ],
新建一個PasspordAdminServiceProvider來實現我們自己的PasswordGrant,別忘了添加到config/app.php的providers配置段中
AppProviders/PasspordAdminServiceProvider
app->make(AdminUserPassportRepository::class), $this->app->make(LaravelPassportBridgeRefreshTokenRepository::class) ); $grant->setRefreshTokenTTL(Passport::refreshTokensExpireIn()); return $grant; } }
新建AdminUserPassportRepository,Password的驗證主要通過getUserEntityByUserCredentials,它讀取配置的guards對應的provider來做認證,我們重寫該方法,通過傳遞一個參數來告訴它我們要用哪個guard來做客戶端認證
get("guard") ?: "api";//其實關鍵的就在這里,就是通過傳遞一個guard參數來告訴它我們是使用api還是admin_api provider來做認證 $provider = config("auth.guards.{$guard}.provider"); if (is_null($model = config("auth.providers.{$provider}.model"))) { throw new RuntimeException("Unable to determine user model from configuration."); } if (method_exists($model, "findForPassport")) { $user = (new $model)->findForPassport($username); } else { $user = (new $model)->where("email", $username)->first(); } if (!$user) { return; } elseif (method_exists($user, "validateForPassportPasswordGrant")) { if (!$user->validateForPassportPasswordGrant($password)) { return; } } elseif (!$this->hasher->check($password, $user->password)) { return; } return new User($user->getAuthIdentifier()); } }
登錄和單用戶系統一樣,只是在請求oauth/token的時候帶上guard參數,示例代碼如下:
Admin/Controllers/Auth/LoginController.php
middleware("guest")->except("logout"); } /** * 獲取登錄TOKEN * @param LoginRequest $request * @return IlluminateHttpJsonResponse */ public function token(LoginRequest $request) { $username = $request->get("username"); $user = AdminUser::orWhere("email", $username)->orWhere("phone", $username)->first(); if ($user && ($user->status == 0)) { throw new UnauthorizedHttpException("", "賬號已被禁用"); } $client = new Client(); try { $request = $client->request("POST", request()->root() . "/api/oauth/token", [ "form_params" => config("passport") + $request->only(array_keys($request->rules())) + ["guard" => "admin_api"] ]); } catch (RequestException $e) { throw new UnauthorizedHttpException("", "賬號驗證失敗"); } if ($request->getStatusCode() == 401) { throw new UnauthorizedHttpException("", "賬號驗證失敗"); } return response()->json($request->getBody()->getContents()); } /** * 退出登錄 */ public function logout() { if (Auth::guard("admin_api")->check()) { Auth::guard("admin_api")->user()->token()->delete(); } return response()->json(["message" => "登出成功", "status_code" => 200, "data" => null]); } }
轉載請注明:?轉載自Ryan是菜鳥 | LNMP技術棧筆記
如果覺得本篇文章對您十分有益,何不 打賞一下
本文鏈接地址:?Laravel Passport API 認證使用小結
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/25579.html
showImg(https://segmentfault.com/img/bV6aHV?w=1280&h=800); 社區優秀文章 Laravel 5.5+passport 放棄 dingo 開發 API 實戰,讓 API 開發更省心 - 自造車輪。 API 文檔神器 Swagger 介紹及在 PHP 項目中使用 - API 文檔撰寫方案 推薦 Laravel API 項目必須使用的 8 個...
摘要:在本教程中,我們將了解如何在應用中使用認證。當用戶通過登錄時,會生成令牌并將其發送給用戶,該用戶可用于身份驗證。提供,可以毫無困難地使用認證。服務提供者我們使用的最新版本,它可以使用包發現并自動注冊服務。 showImg(https://segmentfault.com/img/remote/1460000019095408?w=1000&h=526); 在本教程中,我們將了解如何在 ...
摘要:第一部分安裝第一步使用安裝第二步服務提供器使用框架注冊自己的數據庫遷移目錄,因此在注冊提供器后,就應該運行的遷移命令來自動創建存儲客戶端和令牌的數據表第三步接下來,運行命令來創建生成安全訪問令牌時所需的加密密鑰,同時,這條命令也會創建用于生 第一部分 安裝Passport(laravel/passport) 第一步. 使用 Composer 安裝 Passport :composer...
摘要:使用進行測試注冊接口,注冊成功后返回與用戶名登錄接口詳情接口參考了簡書浪來了的認證應用實戰 安裝larave laravel new passport_demo cd passport_demo && composer install 將 .env 中數據庫配置修改為自己的數據庫配置 DB_DATABASE=homestead DB_USERNAME=homestead DB_P...
摘要:本文來自原文鏈接歡迎作客我們的學習群比如說你要給你的手機用戶創建,使用的是你已有的系統里的數據庫,尤其是用戶數據。 本文來自pilishen.com----原文鏈接; 歡迎作客我們的php&Laravel學習群:109256050 比如說你要給你的手機APP用戶創建API,使用的是你已有的Laravel系統里的數據庫,尤其是用戶數據。現在我們來看一下,這里使用的是Laravel Pas...
閱讀 1833·2021-09-22 15:23
閱讀 3255·2021-09-04 16:45
閱讀 1842·2021-07-29 14:49
閱讀 2767·2019-08-30 15:44
閱讀 1523·2019-08-29 16:36
閱讀 1038·2019-08-29 11:03
閱讀 1504·2019-08-26 13:53
閱讀 504·2019-08-26 11:57