Lumen: add middleware to package defined routes - laravel

I have a problem with adding middleware to existing routes of a vendor package. I building an API on top of Lumen (micro-services framework created by Laravel). I am using Passport for oauth authentication and imported this package: https://github.com/dusterio/lumen-passport to use Passport in Lumen. I have implemented a custom route for requesting a token and want to block requests to the existing passport route: /oauth/token. But I also need the route myself in order to redirect token requests from my custom route.
I have tried to override the existing route like this:
$app->post('/oauth/token', [
'middleware' => 'reject',
'uses' => '\Dusterio\LumenPassport\Http\Controllers\AccessTokenController#issueToken'
]);
But this throws a 500 back at me without Exception tracing.
I am using a custom route for requesting a token in order to set the set the token scope based on the role of a user. I am using the scope to check the role of a user (or app with other grant types), the normal token route of Passport should be blocked to everyone except Lumen self. With this only Lumen should be able to set the scope.
TLDR: How can I add middleware to package defined routes in Lumen.

The latest merge of https://github.com/dusterio/lumen-passport supports prefixing the passport routes.
I added "dusterio/lumen-passport": "dev-master", to my composer.json and Dusterio\LumenPassport\LumenPassport::routes($app, [ 'prefix' => 'api/v1/protected', 'middleware' => 'reject', ]); at the end of my bootstrap/app.php.
See this issue for additional information: https://github.com/dusterio/lumen-passport/issues/31

Related

Calling the right guard in middleware for Multi-auth system

I am adding a custom authentication system via guards , models and providers.
After trying to read some documentation and articles, I am bit confused about the different way of invoking guards and middleware
Question 1:
So, if I want to invoke (default) authentication in a particular route (as defined in auth.php as "default => [ 'guard' => 'web' ... , is it
'middleware' => ['auth']]
Does this mean the default auth ? Or the middleware "auth" - which is included in the Kernel.php as below
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
if i want the default auth as defined in "web" of config/auth.php
should it be
'middleware' => ['auth']] or
'middleware' => ['web']] or
'middleware' => ['auth:web']]
Question 2:
Now there is a middleware group called "web" which has useful things like StartSession, EncryptCookies, CSRF Protection, - so if I have a custom guard "abcguard" - is session management, cookie encryption done through some mechanism or I should explicitly add that middleware "web" in my routes /route-group?
Question 3:
what if I have a custom guard called "abcguard" defined in auth.php as such
and I have a middleware group called abcguard (just for illustration purpose) -- how do I make sure that that a route dashboard is available after the abcguard authentication and passing though middleware abcguard
Is this the right way?
'middleware' => ['auth:abcguard', abcguard]]
How does Laravel know which one is authentication and which one is just a middleware? Or is "guard" just a name for another middleware - the only specific behaviour is that a guard determines how users are authenticated and a middleware might just check if an user is authenticated?
Q4 - In the statement below, how does laravel find out which abcguard is a guard and which is a middlewar group?
'middleware' => ['auth:abcguard', abcguard]]
First, you seem to confuse web middleware group (defined in Kernel) with web guard (authentication mechanism using session) for auth middleware, and they are even not related TBH. Guard is used to authenticate users, and middleware group just holds different middlewares for your web routes. If in your auth.php config, you have default guard web, the 'middleware' => 'auth' will end up using web guard. In case you want to use other guard, you will need to use 'middleware' => 'auth:other_guard'
Again, web middleware group only holds middlewares for ALL of your web routes. You should not add auth to all of them, for sure.
The right way will be 'middleware' => ['auth:abcguard', 'abcguard'], yea. In this case, you have auth middleware using abcguard guard and abcguard middleware group.
When you write auth:abcguard you are calling auth middleware and passing abcguard as argument to it's handle function. Same if it was web - default session guard, or api - default auth token, or sanctum - sanctum's session cookie. Middleware groups are defined in your App\Http\Kernel::class. In case you have abcguard middleware group there, you will be using all middlewares defined in that group.

How to access Sanctum package in custom laravel package

i want to access laravel sanctum auth which is working fine in project routes
I'm making a custom package of api's which needs to use same sanctum authentication with in the custom package routes
use auth sanctum middleware for your routes, See below example.
https://laravel.com/docs/9.x/sanctum#protecting-routes
I was having the same problem, but I found that the packet routes did not have a default guard and the session was not accessible through the packet.
The solution was to add the 'web' middleware to the routes.
Before:
Route::get('/dashboard', [HomeController::class, 'index'])->middleware(['auth:sanctum'])->name('dashboard');
After:
Route::get('/dashboard', [HomeController::class, 'index'])->middleware(['web', 'auth:sanctum'])->name('dashboard');
For those who don't understand why this happens, the question is simple, the 'web' guard is automatically added to the routes that are in the web.php file, but for some reason this doesn't happen with the routes of packages.
Why is the 'web' guard necessary?
Actually, the 'web' guard is not needed, the point is that it bundles various middlewares including: \Illuminate\Session\Middleware\StartSession, which is what handles the user session, so if you don't want to include the 'web' guard in the routes, you you can create a custom middleware group with everything needed for your routes to work in the app\Http\Kernel.php file and the problem will be solved.

Laravel - Protect API routes

I have Laravel application with VUEJS as front-end,
I am getting data by creating API Routes.
So for example the route for getting posts data will be http://localhost/api/posts
What is the best way to protect my routes?
I saw on laravel documentation that there is:
API athentication https://laravel.com/docs/5.8/api-authentication
also Passport https://laravel.com/docs/5.8/passport
For example now any user can reach to the route http://localhost/api/posts
and he will get json with all posts data.
I want protect that and allow only inner api request from my VUEJS commponent to get the data
I’m assuming you’re going to use the Laravel auth routes to do the authentication, and after the authentication, the next view you’re reaching is the one with all the Vue components.
The solution is simple, even that is on the documentation, the necessary steps should be clarified.
We need to:
Add passport composer require laravel/passport
Make the migrations php artisan migrate
Install passport php artisan passport:install
The fourth step is more complex. We need to open our User.php model file. And first we need to import the HasApiTokens and tell the model to use it.
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
.......
}
Then on our config/auth.php we need to modify the api array and change the driver to passport
'api' => [
//for API authentication with Passport
'driver' => 'passport',
'provider' => 'users',
],
Then on our app/Http/Kernel.php we need to add a middleware to the $middlewareGroups array in the key web.
protected $middlewareGroups = [
'web' => [
................
//for API authentication with Passport
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
Now we can use the auth:api middleware on our api routes.
Route::middleware('auth:api')->group( function(){
...your routes here
});
This is what the CSRF TOKEN doing, it's not quite the same with the API Authorization doing
CSRF Token:
To protect (inner) API or access points from cross-site accessing, See Cross-site_request_forgery
CSRF Token is expired and generated within a randomly time, which will make the program access difficulty
API Authorization:
The API is design to be used from other programs, and you'd like to protect them from non-authorized access
Since API tokens expiration and generation is handle by admin manually, since you'll need to place this API token in your HTML to get your function working, it's not what you searching for here
More details of CSRF protection in Laravel see: Laravel CSRF production document
Generally, we'll protect all the routes POST and PUT routes by default

Can I use OAuth and Auth at the same time in Laravel?

I am doing a project in which I have implemented private chat in Laravel. But for the third party, we use OAuth but i have already used auth() in my project. Can I use both? OAuth is getting token, then communicate with Vue.js. So, I don't want to remove auth() functions in my project. Can you please guide me what to do?
Real time chat system in laravel project. I'm using separate Vue.js with Laravel.
Yes. You can use both OAuth and default Laravel Auth at the same time. In default, Laravel provides routes as web.php and api.php.
web.php: This route uses default Laravel Auth functionality
api.php: Routes defined here uses OAuth functionality
Make sure you use default driver as web in config/auth.php
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],

Laravel api routes with auth

I'm trying to make an api route that's only accessible if the user making the request is logged in. This is what I have in my routes/api.php but it returns
{"error":"Unauthenticated."}
Route::group(['middleware' => ['auth:api'], function () {
Route::post('schedules', ['uses' => 'Api\ScheduleController#store']);
});
Can this be done without laravel passport and how? I only need the route for in-app use for logged in users.
I assumed the login mentioned is on "web" which using "session" as driver.
Your are getting this issue because "web" and "api" guard is using different driver for authentication. Take a look in config/auth.php. The "api" guard is using "token" as it's default driver.
Thus, you have few options to encounter this.
Move the route for "schedules" in web.php. No worry, your ajax will failed if not authenticated. But, take note that anything that involved POST method will require csrf (_token parameter), unless you are using laravel axios
Using authentication using api also which you can refer this tutorial for "token" driver and all your secure routes will be using token in its Authentication header

Resources