使用 Laravel 护照 oauth/token 发送更多数据
Sending more data with Laravel passport oauth/token
所以,我使用的是 Laravel+Passport,目前运行良好。
但是,我想对护照代码做一个小改动(好吧,我希望不在供应商文件夹中),一旦我要求用户更改它的密码,以防他正在做首次登录。
所以,我需要的是两件事(我相信):
1 - 如何向 oauth/token 响应添加更多信息?连同 access_token,我想从数据库中添加一列,即 needsNewPassword=true/false。
2 - 如果 needsNewPassword 为 true,则应用程序将重定向到另一个屏幕,用户将在其中设置新密码。我会设置新密码,删除 needsNewPassword 的标志,然后将新的 access_token 发回给用户。然后,用户将仅使用 access_token。我怎样才能重新生成一个新的 access_token?
感谢您的帮助!若昂
对,
我回答我自己的问题,以防有人需要做同样的事情。也许不是最好的方法,但是 working.What 我做的是:
- 创建一个新路由,例如 /api/login 指向一个方法(确保它在您的中间件之外 "auth",一旦它不在 thi 调用中发送令牌)。例如:
Route::post('/login', 'Auth\LoginController@apiLogin');
在该方法中,您向 oauth/token 发出请求,并根据结果添加所需的字段。
测试
function apiLogin(Request $request) {
$tokenRequest = $request->create('/oauth/token', 'POST', $request->all());
$request->request->add([
"client_id" => 'your_client_id',
"client_secret" => 'your_client_secret',
"grant_type" => 'password',
"code" => '*',
]);
$response = Route::dispatch($tokenRequest);
$json = (array) json_decode($response->getContent());
$json['new_value'] = '123456';
$response->setContent(json_encode($json));
return $response
}
这对我有用。就我而言,我也只有一个应用程序,所以我的 client_id、client_secret、grant_type 和代码是在服务器端添加的。客户端只需要传递用户名(或电子邮件,取决于您使用的是什么)和密码,然后它将获得 access_token 和我想发送的其他信息。
希望这对其他人也有帮助。
干杯,
乔奥
@joao.sauer
您自己的答案就像一个魅力,但如果您不想要更多的自由,您可以扩展 Passport 自己的 AccessTokenController。
一个简单的例子:
use App\Models\User;
use Exception;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use League\OAuth2\Server\Exception\OAuthServerException;
use Psr\Http\Message\ServerRequestInterface;
use Response;
class AccessTokenController extends \Laravel\Passport\Http\Controllers\AccessTokenController
{
public function issueToken(ServerRequestInterface $request)
{
try {
//get username (default is :email)
$username = $request->getParsedBody()['username'];
//get user
$user = User::where('email', '=', $username)->firstOrFail();
//issuetoken
$tokenResponse = parent::issueToken($request);
//convert response to json string
$content = $tokenResponse->getBody()->__toString();
//convert json to array
$data = json_decode($content, true);
if(isset($data["error"]))
throw new OAuthServerException('The user credentials were incorrect.', 6, 'invalid_credentials', 401);
//add access token to user
$user = collect($user);
$user->put('access_token', $data['access_token']);
return Response::json(array($user));
}
catch (ModelNotFoundException $e) { // email notfound
//return error message
}
catch (OAuthServerException $e) { //password not correct..token not granted
//return error message
}
catch (Exception $e) {
////return error message
}
}
}
归功于 Messi89:
Laravel Passport - Customize The Token Response
我找到了一个简单的解决方案,不需要新的请求、控制器或扩展,只需将参数添加到请求并通过应用程序调用 issueToken,它对初学者很有用:
// in routes/api.php
Route::post('/token',function(Request $request){
$request->request->add([
'grant_type' => 'password',
'client_id' => '2',
'client_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
]);
return app()->call('\Laravel\Passport\Http\Controllers\AccessTokenController@issueToken');
});
还可以添加 try...catch 块来处理异常或在发送给客户端之前向响应添加参数
Route::post('/token',function(Request $request){
$request->request->add([
'grant_type' => 'password',
'client_id' => '2',
'client_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
]);
try {
$response = app()->call('\Laravel\Passport\Http\Controllers\AccessTokenController@issueToken');
$newResponse = json_decode($response->content());
// Add parameters to response here
$newResponse->user = ['user'=>'user','pass'=>'pass'];
return Response()->json($newResponse);
}catch (Laravel\Passport\Exceptions\OAuthServerException $e) {
if ($e->statusCode() == 400) {
return response()->json(['message' => 'Invalid request. Please enter username and password.'], $e->statusCode());
} else if ($e->statusCode() == 401) {
return response()->json(['message' => 'Your credentials are incorrect. Please try again.'], $e->statusCode());
}
return response()->json('Something went wrong on the server. Please try later.', $e->statusCode());
}
});
所以,我使用的是 Laravel+Passport,目前运行良好。
但是,我想对护照代码做一个小改动(好吧,我希望不在供应商文件夹中),一旦我要求用户更改它的密码,以防他正在做首次登录。
所以,我需要的是两件事(我相信):
1 - 如何向 oauth/token 响应添加更多信息?连同 access_token,我想从数据库中添加一列,即 needsNewPassword=true/false。
2 - 如果 needsNewPassword 为 true,则应用程序将重定向到另一个屏幕,用户将在其中设置新密码。我会设置新密码,删除 needsNewPassword 的标志,然后将新的 access_token 发回给用户。然后,用户将仅使用 access_token。我怎样才能重新生成一个新的 access_token?
感谢您的帮助!若昂
对,
我回答我自己的问题,以防有人需要做同样的事情。也许不是最好的方法,但是 working.What 我做的是:
- 创建一个新路由,例如 /api/login 指向一个方法(确保它在您的中间件之外 "auth",一旦它不在 thi 调用中发送令牌)。例如:
Route::post('/login', 'Auth\LoginController@apiLogin');
在该方法中,您向 oauth/token 发出请求,并根据结果添加所需的字段。 测试
function apiLogin(Request $request) { $tokenRequest = $request->create('/oauth/token', 'POST', $request->all()); $request->request->add([ "client_id" => 'your_client_id', "client_secret" => 'your_client_secret', "grant_type" => 'password', "code" => '*', ]); $response = Route::dispatch($tokenRequest); $json = (array) json_decode($response->getContent()); $json['new_value'] = '123456'; $response->setContent(json_encode($json)); return $response }
这对我有用。就我而言,我也只有一个应用程序,所以我的 client_id、client_secret、grant_type 和代码是在服务器端添加的。客户端只需要传递用户名(或电子邮件,取决于您使用的是什么)和密码,然后它将获得 access_token 和我想发送的其他信息。 希望这对其他人也有帮助。
干杯, 乔奥
@joao.sauer 您自己的答案就像一个魅力,但如果您不想要更多的自由,您可以扩展 Passport 自己的 AccessTokenController。
一个简单的例子:
use App\Models\User;
use Exception;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use League\OAuth2\Server\Exception\OAuthServerException;
use Psr\Http\Message\ServerRequestInterface;
use Response;
class AccessTokenController extends \Laravel\Passport\Http\Controllers\AccessTokenController
{
public function issueToken(ServerRequestInterface $request)
{
try {
//get username (default is :email)
$username = $request->getParsedBody()['username'];
//get user
$user = User::where('email', '=', $username)->firstOrFail();
//issuetoken
$tokenResponse = parent::issueToken($request);
//convert response to json string
$content = $tokenResponse->getBody()->__toString();
//convert json to array
$data = json_decode($content, true);
if(isset($data["error"]))
throw new OAuthServerException('The user credentials were incorrect.', 6, 'invalid_credentials', 401);
//add access token to user
$user = collect($user);
$user->put('access_token', $data['access_token']);
return Response::json(array($user));
}
catch (ModelNotFoundException $e) { // email notfound
//return error message
}
catch (OAuthServerException $e) { //password not correct..token not granted
//return error message
}
catch (Exception $e) {
////return error message
}
}
}
归功于 Messi89: Laravel Passport - Customize The Token Response
我找到了一个简单的解决方案,不需要新的请求、控制器或扩展,只需将参数添加到请求并通过应用程序调用 issueToken,它对初学者很有用:
// in routes/api.php
Route::post('/token',function(Request $request){
$request->request->add([
'grant_type' => 'password',
'client_id' => '2',
'client_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
]);
return app()->call('\Laravel\Passport\Http\Controllers\AccessTokenController@issueToken');
});
还可以添加 try...catch 块来处理异常或在发送给客户端之前向响应添加参数
Route::post('/token',function(Request $request){
$request->request->add([
'grant_type' => 'password',
'client_id' => '2',
'client_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
]);
try {
$response = app()->call('\Laravel\Passport\Http\Controllers\AccessTokenController@issueToken');
$newResponse = json_decode($response->content());
// Add parameters to response here
$newResponse->user = ['user'=>'user','pass'=>'pass'];
return Response()->json($newResponse);
}catch (Laravel\Passport\Exceptions\OAuthServerException $e) {
if ($e->statusCode() == 400) {
return response()->json(['message' => 'Invalid request. Please enter username and password.'], $e->statusCode());
} else if ($e->statusCode() == 401) {
return response()->json(['message' => 'Your credentials are incorrect. Please try again.'], $e->statusCode());
}
return response()->json('Something went wrong on the server. Please try later.', $e->statusCode());
}
});