使用 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());
    }
});