简体   繁体   中英

Laravel - Oauth password grant

I find it difficult to wrap my head around the password grant authentication process.

What I'm trying to achieve: A mobile device sends the username and the password of a registered user to the API and gets the access token as a response in JSON form.

What I've achieved so far: The API receives the user credentials (username and password) and authenticates the user using Laravel's built-in Auth authentication system.

I know that at this point I should proceed to Oauth authentication. Once the credentials pass the Auth step, I have the user's username, password (specified in the users table) and I can get the client_id and client_secret from the oauth_clients table, but I'm not sure how to accomplish the rest. Do I need to make another POST request? If yes, then how do I do it from the controller?

I am actually implementing this right now. Let me show you some code.

This is my part of my login function:

// this does the process for getting the access token
$oauth  = AuthorizationServer::performAccessTokenFlow();
// some hacks
$oauth  = (array) $oauth;
// more hacks
$oauth  = json_decode($oauth["\0*\0data"], true);

// checks if a token was actually generated
if(!in_array('bearer', $oauth))
{
    // returns what was generated if the token is missing
    return Responser::error(400, $oauth);
}

You would have to post additional data on your login other than the username and password of the user.

So your post request will contain:

username=the_username
password=the_password
grant_type=password
client_id=the_client_id
client_secret=the_client_secret

note that grant_type=password is constant.

Now you have to check the configurations of the package too found at app/config/packages/lucadegasperi/oauth2-server-laravel/oauth2.php :

You should have the following code:

'password' => array(
    'class'            => 'League\OAuth2\Server\Grant\Password',
    'access_token_ttl' => 604800,
    'callback'         => function($username, $password){

        $credentials = array(
            // change this to username if username is the field on your database
            'email' => $username,
            'password' => $password,
        );

        $valid = Auth::validate($credentials);

        if (!$valid) {
            return false;
        }

        return Auth::getProvider()->retrieveByCredentials($credentials)->id;
    }
),

And you are done.


update

the code above that generates the token is inside this function:

// allow user to login with username or email and password
$user_pass  = array('username'  => $username, 'password' => $password);
$email_pass = array('email'     => $username, 'password' => $password);

// check if input is email and use $email_pass combination or else use $user_pass combination
$login = ($isEmail->passes() ? $email_pass : $user_pass);

// try to authenticate username & password
if (Auth::attempt($login))
{
    // now you are authenticated here
    // get the client id and secret from the database
    // maybe use curl or some hacks
    // login stuff and token generation

}

This is a bit of an old post, but if you are looking to do this without having multiple post requests, you could always just do something like:

//Get Oauth creds
$apiCreds = OauthClient::where('email', Input::get('email'))->first();

//Provide additional post data for password grant
Input::merge([
    'grant_type' => 'password',
    'client_id' => $apiCreds->id,
    'client_secret' => $apiCreds->secret,
    'username' => Input::get('email'),
    'password' => Input::get('password'),
    'scope' => 'all'
]);

//Login
return AuthorizationServer::performAccessTokenFlow();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM