Get user data using access token in laravel passport client app
I've been going absolutely insane about this issue! It just made no freaking sense as to why it kept spitting out the stupid Unauthenticated
error when trying to hit-up a route such as /api/user
. After much searching (MUCH searching), I finally found the answer. If you see this fero from Laracasts, you're my hero!
https://laracasts.com/discuss/channels/laravel/laravel-53-passport-api-unauthenticated-in-postman-using-personal-access-tokensDid you check
app\Providers\RouteServiceProvider.php
?in the
mapApiRoutes()
you can set the middleware. check to make sure
itsauth:api
. if its not, change it. also, remove theauth
middleware from the routeapi.php
file.
Edit:
Once you've made the change to the app\Providers\RouteServiceProvider.php
mentioned above, proceed with the below example.
First things first, we need to retrieve a fresh access_token
. To do this, I'm using the password grant_type
(more info: https://laravel.com/docs/5.4/passport#password-grant-tokens)
To retrieve a fresh access_token
, I've created a new route on routes/web.php
and called it /connect
. I've then placed the code from the above link into it:
Route::get('connect', function (Request $request) {
$http = new GuzzleHttp\Client;
$response = $http->post('http://example.com/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => $request->client_id,
'client_secret' => $request->client_secret,
'username' => $request->username,
'password' => $request->password,
'scope' => ''
],
]);
return json_decode((string) $response->getBody(), true);
});
Using Chrome Postman, you need to:- Set the method to
GET
- Enter the connect URL with the relevant params i.e. http://example.com/connect?client_id=1&client_secret=W2zogh7tiBh2jfHleYuzpViv7dqynDYQ6O07DKLj&username=test@test.com&password=123456
- Click the headers tab (it's next to Authorization), add a key of
Accept
and value ofapplication/json
- Hit the Send button
{
"token_type": "Bearer",
"expires_in": 31535999,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImE0MmFiYjZkNTQ5M2ZjMGQxYzVmM2E3MDFlOTNjMTRlOTQxMTBmNWQ5NmI1ODI0NTBmMmEyM2MwMzQ5OTMwODdiZGUwYTI5ZDU5N2VjYTExIn0.eyJhdWQiOiIxIiwianRpIjoiYTQyYWJiNmQ1NDkzZmMwZDFjNWYzYTcwMWU5M2MxNGU5NDExMGY1ZDk2YjU4MjQ1MGYyYTIzYzAzNDk5MzA4N2JkZTBhMjlkNTk3ZWNhMTEiLCJpYXQiOjE0OTE0Njg4ODIsIm5iZiI6MTQ5MTQ2ODg4MiwiZXhwIjoxNTIzMDA0ODgxLCJzdWIiOiI3NWNlZDUwMC0xNTQ0LTExZTctOWE4ZS1hZDVmMWFlZTM4OWUiLCJzY29wZXMiOltdfQ.dV3DKDM7IN-oGnZ_Rw10VnYkh9ySlz5i859yO0roZLAYwgmsmEEZK_vpttudUoKmYenqibZQXg6HG4KHRd-cgas_2DpO-7UCkXQYNTriUUAQ4XM6To86EOaf2BW1a07kdVGXTdo_ETQc7heUG0NWQ8-Hrr2NHkSyDULupDs8gDg_fg6xSVsFUEDZB32UIGwquAHT1Y21ZpTdQar0Rag9qOLeZYTR05ro0v9_rQbSoDgJiZE3KT9GbqwU_BegWRmAwY6LmxG4raZpSMgqYEMo3D9D0lJiomOLK4pSjqmi0EVti04zZ6Vg4GHE6S1TgC6IlakV2bMItXTWuZT6T0jEba-3ctaC4K2T8F4P8J6t-99mKY-_zSwgfGm1FErK09qixJlZ4zFsCCT7MgNQVoyu7GkJdTJVlpL1QXLc1QhfrtW11a4gg4Nlja_VyRdB9fZHomgMLpvm_HvSlqEvpeWb8wGkCts9w7ivSNLim-LuFgswGNhTZZqLEbuwB6sJV-l1V0MJCq7_h0yTmLlBdoUkxCaDJJvkUSLk0MUaalAAzY1OCxm-tJcKn31m4yOwf25ZDWf8tWuOTKarEbFyxjB0elkxXQXGe7J7TJAg0tuIEQ8YTL3ExJQ6I7zwtCL83bPOWYRGlJrsX6Lsf0qB-xMVD2DzA3JKDKvZTp5x92kP821",
"refresh_token": "ArOWW0glHjflLpL4fKOsrNUXT5v91u+CjwcE8LBvH7GJsaM0gWaFe8GH9zXjh8SHew+cg7v1IMiIPLYSVdf7h8oOeV7wgwjChI9YM0Kt6iE4wOXJuy0VwPSCj+danHDuWC3nJWYLrPydTE3h/jgFNjWEPfgXGLfiRWjWQMozddz5EWd4pvUI7J64Lw6cMCg/BslZLHtfN7IWoC1RQGp5K0cGO0QmZfsGMSzsoSUNFjv16BXiKSqlNvs5aGhxErFY4wEOKqBifXUkb3SwnK/iHKg3irmqj4fOf/aKNyCdd/PJCHrRPocrW83oM1sjq7eDufEIlgxmy7uRset8GLAWjx/n6rzkxz2QM0/9Lyc/XN9OL00XBYjA47a1wL55qUUUYWevaFwxWX8LG2UjBf9Vv2lfvLcBBkbgqpalePMDh6wb8IDyJek4BbvZtJ1VZ/l+A9XXY9rQt/hIDdoOAtib8CGr9/CERFIrByZa3TEJBCLAa2FvJSIhHVnKvnuvZX3e9qhTkgHqowJrWg2C3VyPDQYAdIhdpTEvs0pcGSAZWhwXfu9xKQOeyRTEScbLKQmuW+sGbwU+qfdLgh/BR5kW4TMer4TIzWKSuHsqmibgiUwaQkwTrtjH2Xz9Z9XmAbVzJ8pqbEZPe7t5whXDoRSnAwWymdxk2E7SiSsVUA3kX39="
}
Highlight the access_token
string and copy it to a text editor.You'll then need to create a new route in routes/api.php
. The route below will simply output the current API users' info:
Route::group(['prefix' => 'user'], function() {
Route::get('/', function() {
return response()->json(request()->user());
});
});
Once you've done the above, make these changes to Postman:- Set the method to
GET
- Change the URL to point to the API route i.e. http://example.com/api/user
- Click on the headers tab again and add a new key of
Authorization
and value ofBearer access_token_here
(replaceaccess_token_here
with the access token you copied earlier) - Hit the Send button
{
"id": "75ced500-1544-11e7-9a8e-ad5f1aee389e",
"name": "test test",
"email": "test@test.com",
"created_at": "2017-03-30 23:29:03",
"updated_at": "2017-03-30 23:29:03"
}
Get user data using passport access token - Laravel
I've reached to way to do so eventually by sending a request to the api in the other machine while adding the token in the header:
public function authenticateUser($token) {
$client = new \GuzzleHttp\Client();
try {
$response = $client->request('GET', env('APP_API_URL') . '/api/v2/user_data', [
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer ' . $token,
],
]);
$request = (string) $response->getBody();
$request = json_decode($request);
$user = User::where('email', $request->data->user->email)->first();
Auth::login($user, true);
} catch (RequestException $e) {
dd('Something went wrong while connection to the api');
}
}
Laravel Passport Get Client ID By Access Token
So, no answers ...
I was able to resolve the issue by consuming my own API, finally I came up with simpler authentication flow, the client need to send their id & secret with each request, then I consumed my own /oauth/token
route with the sent credentials, inspired by Esben Petersen blog post.
Once the access token is generated, I append it to the headers of Symfony\Request
instance which is under processing.
My final output like this:
<?php
namespace App\Http\Middleware;
use Request;
use Closure;
class AddAccessTokenHeader
{
/**
* Octipus\ApiConsumer
* @var ApiConsumer
*/
private $apiConsumer;
function __construct() {
$this->apiConsumer = app()->make('apiconsumer');
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$response = $this->apiConsumer->post('/oauth/token', $request->input(), [
'content-type' => 'application/json'
]);
if (!$response->isSuccessful()) {
return response($response->getContent(), 401)
->header('content-type', 'application/json');
}
$response = json_decode($response->getContent(), true);
$request->headers->add([
'Authorization' => 'Bearer ' . $response['access_token'],
'X-Requested-With' => 'XMLHttpRequest'
]);
return $next($request);
}
}
I used the above middleware in conjunction with Passport's CheckClientCredentials
.protected $middlewareGroups = [
'web' => [
...
],
'api' => [
'throttle:60,1',
'bindings',
\App\Http\Middleware\AddAccessTokenHeader::class,
\Laravel\Passport\Http\Middleware\CheckClientCredentials::class
],
];
This way, I was able to insure that $request->input('client_id')
is reliable and can't be faked. Laravel Passport API: Retrieve Authenticated Token
You can use:
Auth::user()->token()
function to get token model. This is object of class "Token extends Model" so you should be able to use it like any other model.In addition in my project I also have that model:
namespace App;
use Illuminate\Database\Eloquent\Model;
class OauthAccessToken extends Model
{
//
}
and relation:class User extends Authenticatable
{
//...
public function accessTokens()
{
return $this->hasMany('App\OauthAccessToken');
}
}
So I can simply access all tokens and for example delete them:Auth::user()->accessTokens()->delete();
Laravel 9 - Not able to generate token with passport
accessToken is correct just don't forget use:
use Laravel\Passport\HasApiTokens;
instead of:use Laravel\Sanctum\HasApiTokens;
This is correct: $token = $user->createToken('Laravel Password Grant Client')->accessToken;
Related Topics
Speeding Up Large Numbers of MySQL Updates and Inserts
How Would You Transform a Pre-Existing Web App into a Multilingual One
How to Use a PHP Class from Another File
Function to Add Dashes to Us Phone Number in PHP
How Does This Pcre Pattern Detect Palindromes
Get User Data Using Access Token in Laravel Passport Client App
Share Variables/Memory Between All PHP Processes
In a PHP5 Class, When Does a Private Constructor Get Called
Paypal Ipn Bad Request 400 Error
Creating a File Progress Bar in PHP
Imagemagick Brew Installation with PHP Module in MAC Os X
Why Should I Never Run 'Composer Update' in Production
Codeigniter $This->Input->Post() Empty While $_Post Is Working Correctly
Best Way to Escape and Create a Slug
Echo 'String' While Every Long Loop Iteration (Flush() Not Working)