Hi there,
like my last question here I hope you can help me again.
Im using Laravel 5.5 with passport 4.0
I already followed the documentation:
https://laravel.com/docs/5.5/passport#password-grant-tokens
But I will only use the method to grant tokens by credetials.
Because the connection is used by a smartphone I setted the configuration in the
//AuthServiceProvider
public function boot()
{
$this->registerPolicies();
Passport::routes();
Passport::enableImplicitGrant();
Passport::tokensExpireIn(Carbon::now()->addDays(config('APP_ACCESS_TOKEN_EXPIRE_IN')));
Passport::refreshTokensExpireIn(Carbon::now()->addDays(config('APP_REFRESH_TOKEN_EXPIRE_IN')));
}
like this.
I added the 'enableimplicitGrant' cause the documentation called that as best practice for conecitons to mobile-devices.
I used the artisan commands
php artisan passport:client --password
php artisan passport:keys
The rest of my configuration looks like this:
//config/database.php
'mysql' => [
[...]
'prefix' => '',
'strict' => true,
'engine' => 'InnoDB', //changes from 'null'
],
//config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport', //changed from 'token'
'provider' => 'users',
],
],
//config/app.php
/*
* Package Service Providers...
*/
Laravel\Passport\PassportServiceProvider::class, //added
And the User-Model was extended:
//User.php
[...]
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens,Notifiable;
[...]
So the login-Request as well as the register-request enters the particular controller
//loginController.php
class LoginController extends Controller
{
use IssueTokenTrait;
private $client;
public function __construct()
{
$this->middleware('guest')->except('logout');
$this->client = Client::find(1); //there is only one client present in the database
}
public function login(ApiRequest\AppLoginRequest $request) {
return $this->issueToken($request, 'password');
}
public function refresh(ApiRequest\AppLoginRequest $request) {
$this->validate($request, [
'refresh_token' => 'required'
]);
return $this->issueToken($request, 'refresh_token');
}
public function logout(Request $request) {
$accessToken = Auth::user()->token();
DB::table('oauth_refresh_tokens')
->where('access_token_id', $accessToken->id)
->update(['revoked' => true]);
$accessToken->revoke();
return response()->json([], 204);
}
}
The used IssueTokenTrait - The params-array should be built according to the documentation.
//IssueTokenTrait.php
public function issueToken(Request $request, $grant_type, $scope = '*') {
$params = [
'grant_type' => $grant_type,
'client_id' => $this->client->id,
'client_secret' => $this->client->secret,
'username' => $request->username ?: $request->email,
'password' => $request->password,
'scope' => $scope,
];
$request->request->add($params);
$proxy = Request::create('oauth/token', 'POST');
return Route::dispatch($proxy);
}
But every time I only get the response:
{
"error": "unsupported_grant_type",
"message": "The authorization grant type is not supported by the authorization server.",
"hint": "Check the `grant_type` parameter"
}
I already rummaged in the venfor/laravel/passport folder and the vendor/league/oauth2-server/ folder to find where the error-message is thrown.
I found it but it doesn't help me.
Is there someone who can help me with that?
UPDATE
When I call the route oauth/token directly with this body:
username: [email protected]
password: myPassword
grant_type: password
client_id: 1
client_secret: 5SMtQmPo2wKyt6OxWZvRQIhG2lw4n2zxMRxW1nMo
scope: *
Then the reply is correct.
So this is probably the problem?
//loginController
$request->request->add($params);
$proxy = Request::create('oauth/token', 'POST');
return Route::dispatch($proxy);
How can I fix this?
Is there an adaption necessary to be laravel 5.5 conform?
UPDATE-2
Even the request i want to forward has the correct header in my opinion:
+headers: HeaderBag {#48
#headers: array:12 [
"host" => array:1 [
0 => "192.168.56.101:8080"
]
"connection" => array:1 [
0 => "keep-alive"
]
"content-length" => array:1 [
0 => "88"
]
"accept" => array:1 [
0 => "application/json"
]
"cache-control" => array:1 [
0 => "no-cache"
]
"origin" => array:1 [
0 => "chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop"
]
"user-agent" => array:1 [
0 => "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36"
]
"postman-token" => array:1 [
0 => "9e01eae8-4252-f530-7fff-370ffdcaac1d"
]
"dnt" => array:1 [
0 => "1"
]
"accept-encoding" => array:1 [
0 => "gzip, deflate"
]
"accept-language" => array:1 [
0 => "en,de-DE;q=0.9,de;q=0.8,en-US;q=0.7"
]
]
Is the Content-Type missing in the request-header?
CONCLUSION, TLDR
$params = [
'grant_type' => $grant_type, //is called as 'password'
'client_id' => $this->client->id, //only one password client present, ID = 1
'client_secret' => $this->client->secret, //client secret from database
'username' => $request->username ?: $request->email, //login or register, so credentials will be sent
'password' => $request->password,
'scope' => $scope, //is setted to '*' per default
];
- I don't want to deliver the ID and the SECRET to the mobile devices for connecting so I extend the request with
$request->request->add($params);
$proxy = Request::create('oauth/token', 'POST');
return Route::dispatch($proxy);
- when calling the dispatch-address directly the process works
- the content-type-header seems not be the problem, the error occurs in both cases
- changing the redirect-url of the client in the database helps not, redirecting to 'http://localhost' as defined should not working because the laravel is served as 192.168.56.101:8080
UPDATE-3 - PROBLEM ISOLATED
The problem is to use custom requests when entering the login-method.
The request ist then used in the IssueToken-method but there a new request is built and dispatched to a new route.
I cannot figure out how but the endpoint of the oauth/token-route get a request object of an interface not used befor but has still access to the data from the first request as long as this is a type hinted Illuminate\Http\Request-object.
Check out this thread may we will find the solution there:
https://laracasts.com/discuss/channels/laravel/laravel-passport-using-custom-request