Laravel Passport: auth:api behaving like auth:web - php

I am trying to implement passport in my application to authenticate the api calls. I have done the configuration as mentioned in the official documentation.
I have this in my auth guard:
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
And, this in my AuthServiceProvider's boot() method:
Passport::routes();
And this is the route I am trying to access:
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::group(['namespace' => 'Api', 'middleware' => 'auth:api'], function () {
// Login Controller
Route::get('/getclc', 'PreController#getClc');
});
I am sending the header in the request like this:
Authorization:Bearer $accessToken
My question is: 1. When a protected route is requested, it sends me to login page, but I want it to return the 401. How can I do that?
My laravel version is 5.4.33.

When authentication fails, Laravel throws an AuthenticationException exception. This exception is handled by your Laravel exception handler, and eventually calls the unauthenticated() method in your app/Exceptions/Handler.php file.
You can see from that method that if your request expects a json response, you'll get a 401 Unauthenticated response. However, if you're not expecting a json response, it just redirects to the route named "login". This will obviously fail if you don't have a route named "login".
Your request "expectsJson" when you send either the "X-Requested-With: XMLHttpRequest" header, or the "Accept: application/json" header. Otherwise, it is considered a normal web request.
If you'd like to change how your application handles unauthenticated users, the unauthenticated() method is the one to change.

Add this code on Headers on postman.
key Value
Accept application/json
Thanks

Related

Laravel Passport Middleware "auth:api" Always Returns 401 with Valid Token

I am creating a Laravel API and want to secure it with Laravel Passport, however, it seems I can't get authenticated.
I began by securing my API routes using the Middleware auth:api inside my RouteServiceProvider.php
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('auth:api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
I also made sure to change the API driver in my config/auth.php to use passport
'api' => [
'driver' => 'passport',
'provider' => 'users',
'hash' => false,
],
I've then generated token using the methods recommended in the Laravel Docs. I did this inside of Postman.
I then used the Bearer token in the request Headers, along with the Accept and Content-Type being set to application/json (I've seen a lot on this issue in which people said this should be done)
And the Route in my api.php
Route::prefix('auth')->name('auth.')->group(function() {
Route::get('/user', function() { return response()->json(['error' => false, 'message' => 'Hello World']); })->name('user');
});
However, when I send the request I received the same 401 error given by Laravel Foundations Handler.php (I've edited the response to fit my use case but that has no affect on my current issue)
"messsage": "Unauthenticated."
Returning with the following headers;
While doing my research I found a question which described what I was experiencing but it seemed that it has been abandoned and no answer was provided. Any ideas?

Laravel OAuth token not working with Barryvdh\Cors and Passport

I'm working with laravel, using Cors and passport. Everything works great but authentication with the route ({{HOST/oauth/token}}) is not working always get
"Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource"
every other route is working perfectly. SO I just need to tell passport to use cors, I have tried this
In AuthServiceProvider
Passport::routes(null, ['middleware' => [\Barryvdh\Cors\HandleCors::class]]);
and this
Route::group(['middelware' => 'cors'], function () {
Passport::routes();
});
but nothing, login with oauth no working at all. Thank you in advance!!!
change the middleware statement to
Passport::routes(null, ['middleware' => [ \Barryvdh\Cors\HandleCors::class ]]);
refer to https://github.com/barryvdh/laravel-cors/issues/243

Getting 401 in all Laravel api requests

I'm using Laravel with Passport to secure my API with OAuth.
Although, after using a authorized token got with PostMan tool, in all my request using the Passport middleware i'm getting 401.
I installed Laravel twice and looked all around the Internet without success and followed this page for installation: click here.
There is some of my codes:
The route i'm trying to access:
Route::group(['middleware' => 'auth:api'], function(){
Route::get('/user', function (Request $request) {
return $request->user();
});
});
The auth guard:
'guards' => [
//..
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
Update 1: headers of request
Accept: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6ImU5ZDcwZGY0ZjA2MGZhNDk5MzQ1ZjQyN2QxMWY1MDhkZDI2ZWQxODkzZDgxMTcxYWNkZGYxYTkxYzkwNWYxOGUyMTI2NzY0M2QwZmQyOWRiIn0.eyJhdWQiOiIxIiwianRpIjoiZTlkNzBkZjRmMDYwZmE0OTkzNDVmNDI3ZDExZjUwOGRkMjZlZDE4OTNkODExNzFhY2RkZjFhOTFjOTA1ZjE4ZTIxMjY3NjQzZDBmZDI5ZGIiLCJpYXQiOjE1MDE1Mjc2NDYsIm5iZiI6MTUwMTUyNzY0NiwiZXhwIjoxNTMzMDYzNjQ2LCJzdWIiOiIxIiwic2NvcGVzIjpbXX0.dbJ4jddUZx1BT9X81LQIY-Dcx6xdDtmm2nH_C6t7rgFYzRTjab6w7T1NXfzKNlAeyi4iWJAARSBDI32vCeGuAy1ukFvr0qkoEp8UIZEqeeQYYam1Oox_0fuLlJyzwkOIospEc53KZBB0AQrPpW12abxZiZ6asQ9S4AbEJa5N95QFaYRMlxPxEMQOFt28v5148-shawcmtdV-AuAOpvsmap5_f4vQ-NY9R_He0NS4zOOQEY7sPIaRrsQ_XEAJwyiGnrUyufLr02T8wDUcqTskxCtizZx0aHN8i8lz9_X7xBFMHLj4zI4R3wfuZTWlOww07HdBt1oX8PAWvTgA0lw4Sq_xeKa3-MfuCasC4Vh_KWuvHQAfTIuCQw4lPOELfWWaeJTaEuuos7YFbOdoZIHoQWVs4lcisKpHuTGd8bzIPY9GGYsG26LRZB62vX358bijUuurh8p3ajPOt45tmvJnYyaHdf1gW5YwEqbtb07bohMrLFCNhYT0JFZvKa54FRRbB6BLA4lToDA4j1secMKan8mRMLwjEhqyPD0qxBswiMc127ryQ4CLvtKZ75Weno3oAnZ29ZkgtJCTESMzFjd41K-KgrV-s9KTWvfvmOECQUTQz6xUZ5WyVLzPZdBi6wNRYdAp4xRTA1RNUH3TSAP9qYt-xWTwNANXLvL5gBkBjQM
PS: the token is a Personal Access Token generated with Vue component.
when using postman did you force the Content-Type in your header like this
Content-Type: application/json
Try updating your route file this way:
Route::middleware(['auth:api'])->group(function () {
Route::get('/user', function (Request $request) {
return $request->user();
});
});
See more about routing here.
In version 5.6 and later of Laravel, cookies are no serialized/unserialized. However, Passport still expects that the cookies are serialized.
To fix this, you just need to add Passport::withoutCookieSerialization(); to app\Providers\AuthServiceProvider::boot()

Passport authentication is not working in laravel 5.3

I have set-up Laravel using passport as per the documentation here:
https://laravel.com/docs/5.3/passport.
I have written one route in API route and send request http://localhost/laravel_project/public/api/user using postman but its showing me below error:
NotFoundHttpException in RouteCollection.php line 161:
I have the following route (in routes/api.php):
Route::get('/user', function (Request $request) {
return array(
1 => "John",
2 => "Mary",
3 => "Steven"
);
})->middleware('auth:api');
but when I removed ->middleware('auth:api') line in the route it's working fine for me.
How can I fix this?
Also please tell me if I don't want to add passport authentication in my some routes how can i do this?
I was having the same problem, it seems you have to specify the Accept header to application/json as shown by Matt Stauffer here
Some further notes:
Your default Accept header is set to text/html, therefore Laravel will try redirect you to the url /login but probably you haven't done PHP artisan make:auth so it wont find the login route.
When you remove the middleware it will work because you are no longer authenticating your request
To authenticate some routes, just group them using Route::group and auth:api as the middleware
In your routes/api.php you can do this:
Route::group(['middleware' => 'auth:api'], function(){
Route::get('/user', function (Request $request) {
return array(
1 => "John",
2 => "Mary",
3 => "Steven"
);
});
});
All the routes you define inside this group will have the auth:api middleware, so it will need passport authentication in order to access to it.
Outside of this group you can put your api routes that doesn't need authentication.
EDIT: In order to make sure that the route actually exists with the required middleware, run php artisan route:list.

Laravel 5.3 API

When user enter username and password on the the browser and successfully logged in.
I like to make some API requests after user have logged in.
Laravel 5.3 provide api.php in routes folder.
in api.php I have included:
Route::group(['middleware' => ['auth']], function () {
Route::get('/test', function (Request $request) {
return response()->json(['name' => 'test']);
});
});
When requesting domain.com/api/test on the browser, for some reason it is redirecting to /home?
API token is not needed.
If you are specifying routes in api.php, you will need to use the auth:api middleware. So using your example it would be:
Route::group(['middleware' => ['auth:api']], function () {
Route::get('/test', function (Request $request) {
return response()->json(['name' => 'test']);
});
});
Notes about Token auth and Laravel 5.3:
If you've setup laravel's default auth system, you will also need to add a column for api_token to the user table. If you are using DB seeders, you might want to add something like:
$table->char('api_token', 60)->nullable();
to your users table seeder. Alternatively just add the column manually and fill that column with a random 60-char key.
When making the request, you can add the api_token as a URL/Querystring parameter like so:
domain.com/api/test?api_token=[your 60 char key].
You can also send the key as a header (if using Postman or similar), i.e:
Header: Authorization, Value: Bearer [your 60 char key].
I order to get a useful error if the token is incorrect, and not just be redirected to login, also send the following header with all requests:
Header: Accept, Value: application/json. This allows the expectsJson() check in the unauthenticated() function inside App/Exceptions/Handler.php to work correctly.
I found it hard to find clear docs from Laravel about using token auth with 5.3, I think it's because there's a drive to make use of Passport, and it supports tokens in a different way. Here's the article that probably helped most getting it working: https://gistlog.co/JacobBennett/090369fbab0b31130b51
first install the passport as stated here laravel passport installation
while consuming your own api add below line in your config/app.php in middleware section
'web' => [
// Other middleware...
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
now change your route to
Route::group(['middleware' => ['auth:api']], function () {
Route::get('/test', function (Request $request) {
return response()->json(['name' => 'test']);
});
});
now in your config/auth.php change these lines
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
The reason you are being redirected back to home is because the auth middleware checks if a user session is stored in your browser, but since api middleware does not make use of sessions (see app\http\kernel.php), your request is considered unauthenticated
If you would like to perform simple APIs that utilize sessions, feel free to add them in your web routes, and make sure to secure them by grouping them inside an auth middleware.
The standard behaviour in Laravel 5.5 is to delegate handling of authentication exceptions to app/Handler::unauthenticated(), in your project's application code. You'll find the code in there that redirects to the login page, and you can override it or perform further tests and contextualization in there. In previous versions of Laravel, 5.3 among them I believe, this exception handling was executed way down within the Laravel library within the vendor folder.

Categories