2016-12-17 4 views
4

Laravel에 Passport를 사용하지만 다른 모델 (사용자가 아님)을 사용하는 사용자 지정 가드를 추가하려고하지만이 가드에 대해 사용자를 설정하려고 시도하면 작동하지 않습니다.Laravel Passport 다른 모델을 사용하십시오.

설정/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 경로를 액세스 할 수 없습니다. 'conference'가드의 제공자를 '사용자'로 변경하면 문제없이 작동합니다.

내가 무엇을 놓치고 있습니까?

답변

1

사용자 모델 만 '참가자'로 변경하면 공급자를 공급자의 '참가자'로 바꿀 수 있습니다.

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 }

: 다중 인증 내가 임시 해결책을 발견, 아이디어는 https://github.com/laravel/passport/issues/161

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

  1. Laravel \ 여권 \ brigde입니다 \ UserRepository.php 파일 추가에서 온다
    1. League \ OAuth2 \ Server \ Grant \ PasswordGrant.php 78 행 추가

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

    94 라인처럼 $ 공급자를 추가 :

    $user = $this->userRepository->getEntityByUserCredentials(
         $username, 
         $password, 
         $this->getIdentifier(), 
         $client, 
         $provider 
        ); 
    
      같은
    1. 쓰기 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에
    1. 은 특정 메소드를 호출

    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을 게시 할 수 있습니다.