Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending more data with Laravel passport oauth/token

So, I'm using Laravel+Passport and so far is working fine.

But, I would like to made a small change to the passport code(well, not in the vendor folder, I hope), once that I would request the User to change it's password in case that he is doing the first login.

So, what I would need is two things (I believe):

1 - How can I add one more info to the oauth/token response? Together with the access_token, I would like to add one column from the DB that is needsNewPassword=true/false.

2 - In case that needsNewPassword is true, then, the app will redirect to another screen, where the user will set a new password. I would set the new password, remove the flag for needsNewPassword and send back a new access_token to the user. The user then, would use only that access_token. How can I regenerate a new access_token?

Thanks for you help! João

like image 795
joao.sauer Avatar asked Apr 03 '17 01:04

joao.sauer


2 Answers

Right,

I answering my own question, in case someone needs to do the same. Maybe is not the best way, but is working.What I did is:

  • Create a new route, like /api/login that points to a method (be sure that is Outside of your middleware "auth", once that it's not sending the token in thi call). E.g: Route::post('/login', 'Auth\LoginController@apiLogin');
  • in the method, you do a request to the oauth/token and, with the result, you add the fields that you want. test

    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
    }
    

    This is working for me. In my case, I also have just one app so, my client_id, client_secret, grant_type and code is added in the server side. The client only need to pass username(or email, depends of what you are using) and password and then it will get the access_token and the other info that I want to send as well. Hope that this helps someone else too.

Cheers, joao

like image 192
joao.sauer Avatar answered Nov 06 '22 20:11

joao.sauer


@joao.sauer Your own answer is working like a charm, but if you wan't a bit more freedom, you could extend Passport's own AccessTokenController.

A simple example:

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
        }
    }
}

credits to Messi89: Laravel Passport - Customize The Token Response

like image 28
Spekkie Avatar answered Nov 06 '22 20:11

Spekkie