2016-12-17 137 views
4

我想添加一個自定義警衛Laravel使用護照,但與不同的模型(不是用戶),但當我嘗試設置用戶這個警衛它不工作。Laravel護照使用不同的模型

配置/ auth.php:

<?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, 
    ], 
], 

]; 

控制器我設置自定義後衛用戶:

auth()->guard('conference')->setUser($participant); 

api.php:

Route::group(['prefix' => '{activity}', 'middleware' => ['auth:conference', 'api']], function() { // 

    Route::group(['prefix' => 'participant/{participant}'], function() { 
     Route::any('join', 'API\[email protected]'); 

    }); 
}); 

參與者模型:

use Laravel\Passport\HasApiTokens; 
use Illuminate\Foundation\Auth\User as Authenticatable; 

class Participant extends Authenticatable 
{ 
    use Enums, SoftDeletes, RequiresUUID, HasApiTokens, Notifiable; 

但我無法訪問我獲得401的路線。當我將'會議'後衛的提供者更改爲'用戶'時,它的工作原理沒有問題。

我缺少什麼?

回答

1

如果您只是將用戶模型更改爲「參與者」,則可以將提供者替換爲api中的「參與者」。多AUTH我找到了一個臨時解決方案,想法來源於https://github.com/laravel/passport/issues/161

http://esbenp.github.io/2017/03/19/modern-rest-api-laravel-part-4/

  1. Laravel \護照\多橋\ UserRepository.php文件中加入:

public function getEntityByUserCredentials($username, $password, $grantType, ClientEntityInterface $clientEntity, $provider) { 
 
\t \t $provider = config('auth.guards.' . $provider . '.provider'); 
 
\t \t if (is_null($model = config('auth.providers.' . $provider . '.model'))) { 
 
\t \t \t throw new RuntimeException('Unable to determine authentication model from configuration.'); 
 
\t \t } 
 
\t \t if (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 \t if (!$user) { 
 
\t \t \t return; 
 
\t \t } elseif (method_exists($user, 'validateForPassportPasswordGrant')) { 
 
\t \t \t if (!$user->validateForPassportPasswordGrant($password)) { 
 
\t \t \t \t return; 
 
\t \t \t } 
 
\t \t } elseif (!$this->hasher->check($password, $user->getAuthPassword())) { 
 
\t \t \t return; 
 
\t \t } 
 
\t \t return new User($user->getAuthIdentifier()); 
 
\t }

  1. League \ OAuth2 \ Server \ Grant \ PasswordGrant.php 78 line add

    $ provider = $ this-> getRequestParameter('provider',$ request);

和94行添加$提供商,如:

$user = $this->userRepository->getEntityByUserCredentials(
     $username, 
     $password, 
     $this->getIdentifier(), 
     $client, 
     $provider 
    ); 
  • 寫LoginProxy(實際上應該是接收在構造不同模型)等:
  • class LoginProxy { 
     
    \t const REFRESH_TOKEN = 'refreshToken'; 
     
    \t private $client; 
     
    \t private $user; 
     
    \t public function __construct(User $user, Client $client) { 
     
    \t \t $this->user = $user; 
     
    \t \t $this->client = $client; 
     
    \t } 
     
    \t public function attemptLogin($mobile, $password) { 
     
    \t \t $user = $this->user->where('mobile', $mobile)->first(); 
     
    \t \t if (!is_null($user)) { 
     
    \t \t \t return $this->proxy('password', [ 
     
    \t \t \t \t 'username' => $mobile, 
     
    \t \t \t \t 'password' => $password, 
     
    \t \t \t ]); 
     
    \t \t } 
     
    \t \t return response()->json('error for 401', 401); 
     
    \t } 
     
    \t public function attemptRefresh() { 
     
    \t \t $refreshToken = $this->request->cookie(self::REFRESH_TOKEN); 
     
    \t \t return $this->proxy('refresh_token', [ 
     
    \t \t \t 'refresh_token' => $refreshToken, 
     
    \t \t ]); 
     
    \t } 
     
    \t public 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 \t return 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 } 
     
    \t public 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 } 
     
    }

  • 在你的LoginController,調用某些方法:
  • class LoginController extends Controller { 
     
    \t private $loginProxy; 
     
    \t public function __construct(LoginProxy $loginProxy) { 
     
    \t \t $this->loginProxy = $loginProxy; 
     
    \t } 
     
    \t public function login(LoginRequest $request) { 
     
    \t \t $mobile = $request->get('mobile'); 
     
    \t \t $password = $request->get('password'); 
     
    \t \t $provider = $request->get('provider'); 
     
    \t \t return $this->loginProxy->attemptLogin($mobile, $password, $provider); 
     
    \t } 
     
    \t public function refresh(Request $request) { 
     
    \t \t return $this->response($this->loginProxy->attemptRefresh()); 
     
    \t } 
     
    \t public function logout() { 
     
    \t \t $this->loginProxy->logout(); 
     
    \t \t return $this->response(null, 204); 
     
    \t }

    現在,你可以發佈不同的供應商PARAMS它。