Laravel Passport use Different Model
我想向使用Passport但具有不同型号(而非用户)的Passport的Laravel添加自定义防护,但是当我尝试为该防护设置用户时,它不起作用。
config / auth.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | <?php return [ /* |-------------------------------------------------------------------------- | Authentication Defaults |-------------------------------------------------------------------------- | | This option controls the default authentication"guard" and password | reset options for your application. You may change these defaults | as required, but they're a perfect start for most applications. | */ 'defaults' => [ 'guard' => 'web', 'passwords' => 'users', ], /* |-------------------------------------------------------------------------- | Authentication Guards |-------------------------------------------------------------------------- | | Next, you may define every authentication guard for your application. | Of course, a great default configuration has been defined for you | here which uses session storage and the Eloquent user provider. | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | Supported:"session","token" | */ 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], 'conference' => [ 'driver' => 'passport', 'provider' => 'participants', ], ], /* |-------------------------------------------------------------------------- | User Providers |-------------------------------------------------------------------------- | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | If you have multiple user tables or models you may configure multiple | sources which represent each model / table. These sources may then | be assigned to any extra authentication guards you have defined. | | Supported:"database","eloquent" | */ 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\\Models\\User::class, ], 'participants' => [ 'driver' => 'eloquent', 'model' => App\\Models\\Participant::class, ], // 'users' => [ // 'driver' => 'database', // 'table' => 'users', // ], ], /* |-------------------------------------------------------------------------- | Resetting Passwords |-------------------------------------------------------------------------- | | Here you may set the options for resetting passwords including the view | that is your password reset e-mail. You may also set the name of the | table that maintains all of the reset tokens for your application. | | You may specify multiple password reset configurations if you have more | than one user table or model in the application and you want to have | separate password reset settings based on the specific user types. | | The expire time is the number of minutes that the reset token should be | considered valid. This security feature keeps tokens short-lived so | they have less time to be guessed. You may change this as needed. | */ 'passwords' => [ 'users' => [ 'provider' => 'users', 'email' => 'spark::auth.emails.password', 'table' => 'password_resets', 'expire' => 60, ], ], ]; |
在控制器中,我正在为自定义防护设置用户:
1 | auth()->guard('conference')->setUser($participant); |
api.php:
1 2 3 4 5 6 7 | Route::group(['prefix' => '{activity}', 'middleware' => ['auth:conference', 'api']], function () { // Route::group(['prefix' => 'participant/{participant}'], function () { Route::any('join', 'API\\ConferenceController@join'); }); }); |
参与者模型:
1 2 3 4 5 6 | use Laravel\\Passport\\HasApiTokens; use Illuminate\\Foundation\\Auth\\User as Authenticatable; class Participant extends Authenticatable { use Enums, SoftDeletes, RequiresUUID, HasApiTokens, Notifiable; |
但是我无法访问获得401的路由。当我将"会议"防护的提供程序更改为"用户"时,它的工作就没有问题。
我想念的是什么?
这可能会有所帮助:
我的AdminAPI网址:https://example.com/api/login
我的客户API网址:https://example.com/api.customer/login
将此添加到任何ServiceProvider(在自定义路由之前,我已经在RouteServiceProvider.php中添加了此内容)
1 2 | // Fix/Support for multiple user with different table by changing provider on api.customer circumstances Config::set('auth.guards.api.provider', request()->input('provider', starts_with(request()->path(), 'api.customer') ? 'customers' : 'users'));` |
,并且必须在config / auth.php
的providers数组中添加自定义提供程序
1 2 3 4 | 'customers' => [ 'driver' => 'eloquent', 'model' => App\\Customer::class, ], |
如果仅将用户模型更改为\\'participants \\',则可以在api中将提供程序替换为\\'participants \\'。多重身份验证我找到了一个临时解决方案,想法来自https://github.com/laravel/passport/issues/161
和http://esbenp.github.io/2017/03/19/modern-rest-api-laravel-part-4/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | public function getEntityByUserCredentials($username, $password, $grantType, ClientEntityInterface $clientEntity, $provider) { \t\t$provider = config('auth.guards.' . $provider . '.provider'); \t\tif (is_null($model = config('auth.providers.' . $provider . '.model'))) { \t\t\tthrow new RuntimeException('Unable to determine authentication model from configuration.'); \t\t} \t\tif (method_exists($model, 'findForPassport')) { \t\t\t$user = (new $model)->findForPassport($username); \t\t} else { \t\t\t$user = (new $model)->where('email', $username)->first(); \t\t} \t\tif (!$user) { \t\t\treturn; \t\t} elseif (method_exists($user, 'validateForPassportPasswordGrant')) { \t\t\tif (!$user->validateForPassportPasswordGrant($password)) { \t\t\t\treturn; \t\t\t} \t\t} elseif (!$this->hasher->check($password, $user->getAuthPassword())) { \t\t\treturn; \t\t} \t\treturn new User($user->getAuthIdentifier()); \t} |
联赛\\\\\\\\ OAuth2 \\\\\\\\ Server \\\\\\\\ Grant \\\\\\\\ PasswordGrant.php 78行添加
$ provider = $ this-> getRequestParameter(\\'provider \\',$ request);
和94行添加$ provider,例如:
1 2 3 4 5 6 7 | $user = $this->userRepository->getEntityByUserCredentials( $username, $password, $this->getIdentifier(), $client, $provider ); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | class LoginProxy { \tconst REFRESH_TOKEN = 'refreshToken'; \tprivate $client; \tprivate $user; \tpublic function __construct(User $user, Client $client) { \t\t$this->user = $user; \t\t$this->client = $client; \t} \tpublic function attemptLogin($mobile, $password) { \t\t$user = $this->user->where('mobile', $mobile)->first(); \t\tif (!is_null($user)) { \t\t\treturn $this->proxy('password', [ \t\t\t\t'username' => $mobile, \t\t\t\t'password' => $password, \t\t\t]); \t\t} \t\treturn response()->json('error for 401', 401); \t} \tpublic function attemptRefresh() { \t\t$refreshToken = $this->request->cookie(self::REFRESH_TOKEN); \t\treturn $this->proxy('refresh_token', [ \t\t\t'refresh_token' => $refreshToken, \t\t]); \t} \tpublic function proxy($grant_type, array $data = []) { \t\t$data = array_merge($data, [ \t\t\t'client_id' => env('PASSWORD_CLIENT_ID'), \t\t\t'client_secret' => env('PASSWORD_CLIENT_SECRET'), \t\t\t'grant_type' => $grant_type, \t\t\t'scope' => '*', \t\t]); \t\t$response = $this->client->post(url('/oauth/token'), [ \t\t\t'form_params' => $data, \t\t]); \t\t$data = json_decode($response->getBody()->getContents()); \t\treturn response()->json([ \t\t\t'token_type' => $data->token_type, \t\t\t'access_token' => $data->access_token, \t\t\t'refresh_token' => $data->refresh_token, \t\t\t'expires_in' => $data->expires_in, \t\t], 200); \t} \tpublic function logout() { \t\t$accessToken = $this->auth->user()->token(); \t\t$refreshToken = $this->db \t\t\t->table('oauth_refresh_tokens') \t\t\t->where('access_token_id', $accessToken->id) \t\t\t->update([ \t\t\t\t'revoked' => true, \t\t\t]); \t\t$accessToken->revoke(); \t} } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class LoginController extends Controller { \tprivate $loginProxy; \tpublic function __construct(LoginProxy $loginProxy) { \t\t$this->loginProxy = $loginProxy; \t} \tpublic function login(LoginRequest $request) { \t\t$mobile = $request->get('mobile'); \t\t$password = $request->get('password'); \t\t$provider = $request->get('provider'); \t\treturn $this->loginProxy->attemptLogin($mobile, $password, $provider); \t} \tpublic function refresh(Request $request) { \t\treturn $this->response($this->loginProxy->attemptRefresh()); \t} \tpublic function logout() { \t\t$this->loginProxy->logout(); \t\treturn $this->response(null, 204); \t} |
现在您可以向其发布不同的提供程序参数。