laravel=パスポートについて多くのことを聞いた後、モバイルアプリで使用するAPIを作成することが私の要件である新しいプロジェクトに実装することを考えました。
したがって、私のモバイルアプリはclient
であり、さらにユーザーがいます。
手順に従いました Taylorによる言及 そしてそれについても読みます ここ 。簡単に言うと、次の手順を実行しました。
laravel/passport
_をインストールしました。php artisan passport:install
_client_id
_を使用して生成された_client_secret
_および_php artisan passport:client
_web.php
_にredirection
およびcallback
ルートを追加しました次に、値Bearer eyJ0eXAiOiJKV1...(token)
を含むヘッダーAuthorization
で_api/user
_(を呼び出してみました
データを受け取りました。とてもシンプルできれい。
しかし、アプリのユーザーにはこれらの詳細はありません。それで、私は Password Grant Tokens を設定することを考えました。これは私の要件に完全に適合します。
今、本当の頭痛が始まります。私は過去3日間これを設定しようとしており、継続的に取得しています
_{"error":"invalid_client","message":"Client authentication failed"}
_
オンラインでフォローしたほとんどすべてのガイドを試しました: リダイレクトの問題 、 少なくとも1つのスコープソリューションを追加 、 P100Yの問題 など.
しかし、私はまだ_invalid client
_エラーを受け取っています。 POSTMANを介して_oauth/token
_に渡すものを次に示します。
_{
"grant_type": "password,"
"client_id": "3,"
"client_secret": "8BUPCSyYEdsgtZFnD6bFG6eg7MKuuKJHLsdW0k6g,"
"username": "[email protected],"
"password": "123456,"
"scope": ""
}
_
任意の助けをいただければ幸いです。
資格情報が正しい場合は最初に資格情報を確認し、次にemail
列が含まれているかどうかを示す\Laravel\Passport\HasApiTokens
特性を使用するモデルテーブルを確認します。テーブルにusername
列または資格情報の検証に使用される他の列がある場合、そのモデルで関数findForPassport
を定義する必要があります。このような、
public function findForPassport($username) {
return self::where('username', $username)->first(); // change column name whatever you use in credentials
}
{project_directory}\vendor\laravel\passport\src\Bridge\UserRepository.php
のユーザー名とパスワードの列を使用してユーザーを検証します
この関数は資格情報を検証し、
public function getUserEntityByUserCredentials($username, $password, $grantType, ClientEntityInterface $clientEntity)
{
if (is_null($model = config('auth.providers.users.model'))) {
throw new RuntimeException('Unable to determine user model from configuration.');
}
if (method_exists($model, 'findForPassport')) { // if you define the method in that model it will grab it from there other wise use email as key
$user = (new $model)->findForPassport($username);
} else {
$user = (new $model)->where('email', $username)->first();
}
if (! $user || ! $this->hasher->check($password, $user->password)) {
return;
}
return new User($user->getAuthIdentifier());
}
2番目のifステートメントに注目すると、そこで起こっていることを知ることができます。
このヘルプを願っています:)
これは、パスワード付与を実装しているため、正しい方向に導くのに役立ちます。
1-これを実行する代わりにステップ4で:
php artisan passport:install
以下を実行して、パスワード付与クライアントを作成します。
php artisan passport:client --password
上記のコマンドは、パスワード付与クライアントの名前を設定するための追加の質問をします。データベースでこの新しいレコードのIDとシークレットを取得してください。
2-POSTMAN Post要求オブジェクトは、次のようなオブジェクト内にラップする必要があります。
'form_params' => [
'grant_type' => 'password',
'client_id' => 'my_client-id',
'client_secret' => 'my_client-secret',
'username' => 'username or email', <-pass through variables or something
'password' => 'my-user-password', <- pass through variables or something
'scope' => '',
],
更新1 2016年10月12日:
この問題をさらに調査すると、私はあなたがいるのとまったく同じ場所に出くわし、パスポートのウサギの穴に飛び込むことを余儀なくされました。
現在、システムは「password」である必要があるときに、クライアント識別子を「authorization_code」として設定しています。私もこの問題に遭遇したので、この問題を解決する方法を調査しています。私は、人々が私が行った場所と私がやってきたことを追跡するのを助けるためにコードを投稿しますが、今は午前2時40分ですので、いくらかの睡眠が必要です。
更新2 2016年10月12日
7時間問題をデバッグしています。クライアントを検証するメソッドがパスポート内にあります。このメソッドは、オブジェクト(上記)に追加した入力を受け取り、渡された内容に基づいてクライアントリポジトリクラスを介してクライアントエンティティを取得しようとします。クライアントが見つかった場合、クライアントエンティティが確認されますクライアントエンティティのインスタンスは、クライアントエンティティインターフェイス内に実際に存在し、データベースからクライアントの資格情報を取得するように見えます。ただし、テストで得たものからNULLを返すコードブロックがあります。これまでのところ、すべてのフィールドが適切に導入されていますが、リポジトリとインターフェースの間には混乱があるようです。エラーがスローされる原因となっています。
最終的には、この問題の解決に近づいていると感じています。あなたの忍耐は大歓迎です。 =)
更新3 2016年10月12日
長期間のデバッグの後、最初の問題が見つかりました。一致しないフィールドがありました。つまり、セットアップの問題です。
SO
この場合の解決策は次のとおりです。
データベース内のすべてのフィールドをダブルチェック with [〜#〜] all [〜#〜]渡される資格情報。ピリオド、ダッシュ、スペースパスワード、クライアントIDまで、クライアントシークレット、有効なリダイレクトURI/URL、grant_types、スコープ(使用している場合):
上記のphp artisanコマンドを使用して作成する必要がない場合は、データベースのクライアントの「password_client」列の下にENUMが1であることを確認してください。
php artisan passport:client --password
あなたが渡す秘密は、あなたのデータベースのキャラクターのキャラクターについてリストされているものと一致することを確認してください
渡すIDが一致し、整数データ型であることを確認してください。
クライアントに何らかの名前が付けられていることを確認してください
パスワード付与を使用する場合、user_id列について心配しないでください。
ルートが正しいことを確認してください
入力するメール(ユーザー名)がデータベース内のユーザーテーブル内の実際のユーザーであることを確認します(または、ユーザーテーブルとして受け入れるようにlaravel 5.3システムをカスタマイズしたテーブル) laravel 5.3システムをカスタマイズする方法に関するリンクを追加し、必要に応じてデフォルトとして別のユーザーテーブルを受け入れます)。
Grant_typeのスペルが正しいことを確認してください
応答ベアラートークン(access_tokenおよびrefresh_tokenを意味する)を受け入れるように設定されていることを確認してください。
それ以外は、このアンサーの上記の部分で説明した最初の手順で、正しい道に戻るはずです。ここには、役立つ類似の手順について言及しているが、別の問題に関連する同じエラーに対処している他の人もいます(特定のシステムセットアップに関連するセットアップの問題の結果だと確信しています)。
これが役立つことを願っています。
すべてのパスポートコマンドの後にphp artisan config:cache
を実行してみてください。
以下のコードを使用してアクセストークンを生成します。
$request->request->add([
'client_id' => '2',
'client_secret' => 'm3KtgNAKxq6Cm1WC6cDAXwR0nj3uPMxoRn3Ifr8L',
'grant_type' => 'password',
'username' => '[email protected]',
'password' => 'pass22'
]);
$tokenRequest = $request->create('/oauth/token', 'POST', $request->all());
$token = \Route::dispatch($tokenRequest);
同じ問題があり、basic.authヘッダーを設定することで修正されました。client_idをユーザー名に、secretをパスワードに設定しました。
それからそれはうまく働きました。
追加のコントローラーやミドルウェアなしでRESTED(POSTMANのようなサービス)を介して動作するLaravel Passport-Password_Grant_Tokenを取得することができました。
デフォルトのAuth-Scaffoldingをlaravel doc's here にインストールします
パスポートをインストールします ドキュメントはこちら
auth-scaffoldingを介してユーザーを登録します
Goto RESTEDまたはPOSTMAN、またはその他の同様のサービス
form_paramsのoauth_clientsテーブルのデータを確認します
Request_body_form_dataではなくRESTEDを使用して、ヘッダーではなく、forms_paramsを書き込み、POSTリクエストを*/oauth/tokenに送信します(完全なURLが必要です)
(必要なform_paramsはgrant_type、client_id、client_secret、ユーザー名およびパスワードです)
4つのキー(token_type、expires_in、access_tokenおよびrefresh_token)と200 OKのステータスを持つオブジェクトを返す必要があります。
これまでのところすべてが成功した場合...
別のRESTEDウィンドウを開きます。
/ api/userにGETリクエストを送信します(完全なURLが必要です)
そしてそれはそれであるはずです。/api/userからの応答としてユーザーオブジェクトを取得する必要があります。
補助金タイプを徹底的に確認してください。
{
"grant_type": "password",
"client_id": 2,
"client_secret":
"username": ,
"password":
"scope": ""
}
上記の例では、パスワードを示しています。次に、テーブルを確認します:oauth_clientsそして、列password_client = 1
の値が
またはpassword_client = 1
でエントリを探します
{"error":"invalid_client","message":"Client authentication failed"}
は、現在送信しているclient_idとclient_secretが次のいずれかであることを意味します。
私にとって、その特定のクライアントのpassword_client列の値は0でした。手動で1に変更しましたが、助けにはなりませんでした。 –カナブ10月4日3時25分
いくつかの答えへのコメントを読んでいると、パスワード付与フローにclient_idとclient_secretの間違ったタイプを使用していることが明らかになります。指定したclient_idとclient_secretのoauth_clientsテーブルでエントリを見つけることで、それを確認できます
"grant_type": "password,"
"client_id": "3,"
"client_secret": "8BUPCSyYEdsgtZFnD6bFG6eg7MKuuKJHLsdW0k6g,"
SELECT * FROM oauth_clients WHERE id = 3 AND secret = '8BUPCSyYEdsgtZFnD6bFG6eg7MKuuKJHLsdW0k6g' AND password_client=1;
oauth_clientsテーブルで、指定されたclient_idおよびclient_secret パスワード付与フローに存在する oauthサーバー。また、手動でタイプを変更しないかどうかクライアントは、その列の値を切り替えるだけで、パスワード付与タイプに新しいクライアントを作成する必要があります。
php artisan migrate
このコマンドは、laravel/passport移行ファイルを移行して、laravel/passportが現在サポートしているタイプごとに2つのデフォルトクライアントを生成します。パスワード付与フローのクライアントを作成することもできます
php artisan passport:client --password
パスワード付与タイプの新しいクライアントがある場合は、/ oauth/tokenに再度POSTを実行して、新しく生成されたclient_idおよびclient_secretでトークンを生成します
私も同じ問題に直面していた、私はこのリンクから解決策を得た。確認してください。 https://github.com/laravel/passport/issues/71
それは言う:あなたはいつもあなたのトークンを取得したいのと同じように/ oauth/tokenを呼び出します。ただし、grant_typeをcustom_requestにしてください。 byPassportCustomRequest($ request)メソッドをUserモデル(または動作するように設定したモデル)に追加する必要がありますパスポート付き)。そのメソッドは、Illuminate\Http\Requestを受け入れ、リクエストを介してユーザーを認証できる場合はユーザーモデルを返すか、nullを返します。
Php artisan passport:client --passwordを使用して新しいパスワードクライアントを作成してみてください。その後、ほとんどの場合、ユーザーはそのパスワードクライアントに割り当てられません。データベース行を編集し、既存のユーザーIDを追加します。
{
"grant_type": "password,"
"client_id": "" <- edited and added user id
"client_secret": "8BU......," <- new secret
"username": "[email protected]," <- email of above added user id
"password": "123456,"<- password
"scope": ""
}
今すぐトークンを取得できることを願っています
クライアントがパスポートサーバーに設定されている場合、リダイレクト/コールバックURLを確認します。リダイレクトURLが正しいことからクライアントIDとシークレットを取得するエントリを確認します。
同じエラーが発生し、リダイレクトURLが正しくないことがわかりました。
/ callbackルートを指す必要があります(Taylorの例では)
すべてを試してもまだ機能しない場合は、この解決策を試してください!スコープを指定してください*。
$query = http_build_query([
'client_id' => 1,
'redirect_uri' => 'http://localhost:3000/callback',
'response_type' => 'code',
'scope' => '*'
]);
私の場合、これが解決策です。確認しました
同じ問題がありました。 php artisan passport:install
を実行すると、CLIENT付与タイプ用とPASSWORD付与タイプ用の2種類のシークレットが発行されます。
CLIENTシークレットを使用してPASSWORDトークンを発行していました。それを変更したら、access_token
とrefresh_token
を通常どおり生成できました。