How to use GATE facades in LUMEN (Laravel 6.2) - php

I'm trying to create an ACL with Lumen.
I want to use the built-in gates/policies to do so.
I've been following the official Lumen Docs:
https://lumen.laravel.com/docs/6.x/authorization
and Laravel Docs:
https://laravel.com/docs/6.x/authorization
to do so. They say I need to register both facades and the gate facade in order to use Gates.
I have the following code inside my AuthServiceProvider.php:
<?php
namespace App\Providers;
use App\User;
use Firebase\JWT\JWT;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Gate;
//use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
class AuthServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Boot the authentication services for the application.
*
* #return void
*/
public function boot()
{
// Here you may define how you wish users to be authenticated for your Lumen
// application. The callback which receives the incoming request instance
// should return either a User instance or null. You're free to obtain
// the User instance via an API token or any other method necessary.
$this->app['auth']->viaRequest('api', function ($request) {
$key = 'pawifjopawiejfpoaiwejfpoji';
$jwt = preg_replace('/^Bearer (.*)/', '$1', $request->header('Authorization'));
$decoded = JWT::decode($jwt, $key, ['HS256']);
return User::where('email', $decoded->email)->first();
});
$this->registerPolicies();
Gate::define('edit-settings', function($user){
return $user->isAdmin;
});
}
}
And I have the bootstrap/app.php set like so, with $app->withFacades() uncommented:
<?php
require_once __DIR__.'/../vendor/autoload.php';
(new Laravel\Lumen\Bootstrap\LoadEnvironmentVariables(
dirname(__DIR__)
))->bootstrap();
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| Here we will load the environment and create the application instance
| that serves as the central piece of this framework. We'll use this
| application as an "IoC" container and router for this framework.
|
*/
$app = new Laravel\Lumen\Application(
dirname(__DIR__)
);
$app->withFacades();
$app->withEloquent();
/*
|--------------------------------------------------------------------------
| Register Container Bindings
|--------------------------------------------------------------------------
|
| Now we will register a few bindings in the service container. We will
| register the exception handler and the console kernel. You may add
| your own bindings here if you like or you can make another file.
|
*/
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
$app->singleton(
Illuminate\Contracts\Console\Kernel::class,
App\Console\Kernel::class
);
/*
|--------------------------------------------------------------------------
| Register Middleware
|--------------------------------------------------------------------------
|
| Next, we will register the middleware with the application. These can
| be global middleware that run before and after each request into a
| route or middleware that'll be assigned to some specific routes.
|
*/
// $app->middleware([
// App\Http\Middleware\ExampleMiddleware::class
// ]);
$app->routeMiddleware([
'auth' => App\Http\Middleware\Authenticate::class,
]);
/*
|--------------------------------------------------------------------------
| Register Service Providers
|--------------------------------------------------------------------------
|
| Here we will register all of the application's service providers which
| are used to bind services into the container. Service providers are
| totally optional, so you are not required to uncomment this line.
|
*/
// $app->register(App\Providers\AppServiceProvider::class);
$app->register(App\Providers\AuthServiceProvider::class);
// $app->register(App\Providers\EventServiceProvider::class);
/*
|--------------------------------------------------------------------------
| Load The Application Routes
|--------------------------------------------------------------------------
|
| Next we will include the routes file so that they can all be added to
| the application. This will provide all of the URLs the application
| can respond to, as well as the controllers that may handle them.
|
*/
$app->router->group([
'namespace' => 'App\Http\Controllers',
], function ($router) {
require __DIR__.'/../routes/web.php';
});
return $app;
And when I now run any http-request with RESTClient (www.restclient.net) against my Lumen API, I get the following error:
Call to undefined method App\Providers\AuthServiceProvider::registerPolicies()
I googled quite a lot on this issue and found some solutions, but none of them worked for me.
Please help

Your provider doesn't have that method. This is the entire AuthServiceProvider that Laravel uses as its base for AuthServiceProvider:
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [];
/**
* Register the application's policies.
*
* #return void
*/
public function registerPolicies()
{
foreach ($this->policies() as $key => $value) {
Gate::policy($key, $value);
}
}
/**
* Get the policies defined on the provider.
*
* #return array
*/
public function policies()
{
return $this->policies;
}
}
registerPolicies isn't doing anything special. It just spins through $policies and registers them; you can do this yourself.
"Unlike Laravel, Lumen does not have a $policies array on its AuthServiceProvider. However, you may still call the policy method on the Gate facade from within the provider's boot method" - Lumen 6.x Docs - Authorization - Defining Policies

Related

Target class [PagesController] does not exist in laravel 8

This error keeps showing up on the browser even though I had tried a few solutions to fix it.
This is the code for PagesController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PagesController extends Controller
{
//
public function index()
{
return view("pages.index");
}
}
Code for routes/web.php:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PagesController;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
// Route::get('/', function () {
// return view('welcome');
// });
Route::get("/", [PagesController::class, 'index']);
Code for RouteServiceProvider.php:
<?php
namespace App\Providers;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
/**
* This namespace is applied to your controller routes.
*
* In addition, it is set as the URL generator's root namespace.
*
* #var string
*/
protected $namespace = 'App\Http\Controllers';
/**
* The path to the "home" route for your application.
*
* #var string
*/
public const HOME = '/home';
/**
* Define your route model bindings, pattern filters, etc.
*
* #return void
*/
public function boot()
{
//
parent::boot();
}
/**
* Define the routes for the application.
*
* #return void
*/
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
//
}
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* #return void
*/
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
/**
* Define the "API" routes for the application.
*
* These routes are typically stateless.
*
* #return void
*/
protected function mapApiRoutes()
{
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
}
Everything just seems working fine to me, I did add the use statement in my web.php but it still shows PagesController and the default namespace in my RouteServiceProvider.php is 'App\Http\Controllers'. The file structure is also correct the PagesController.php is under the Controllers folder. I also tried to use commands to fix it like php artisan config:cache and composer dump-autoload but it did not work. Does anyone detect the mistake that I am making here? Thanks in advance.
In the new version of laravel, it works like this
Add This code
use App\Http\Controllers\PagesController;
and use the route as
Route::get('/', [PagesController::class,'index']);
First check PagesController is not a resource controller. if PagesController is resource controller so you can add bellow code.
php artisan route:list
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
// Route::get('/', function () {
// return view('welcome');
// });
// And use resource route
Route::resource('/', PagesController::class);
use resource route don't added PagesController controller in top. and if not solve please send message me on https://devnote.in I will help you.
If Everything is in the correct folder, I think there is some problem with you route file. Use this statement and check if your Controller can be find:
Route::get('/', 'PagesController#index');
And if it does not work use this one:
Route::get('/', 'App\Http\Controllers\PagesController#index');
it seems that you are upgrading from a previous Laravel version, isn't it?
Check RouteServiceProvider.php from source:
https://github.com/laravel/laravel/blob/master/app/Providers/RouteServiceProvider.php
And make sure to make a comparison to your entire directory with:
https://github.com/laravel/laravel/compare/7.x...master
You could try putting:
use App\Http\Controllers\Controller;
In your PagesController.php as it is now needed in Laravel 8 (https://laravel.com/docs/8.x/controllers#defining-controllers)
I had a similar issue and this is how I solved it.
I included the following code in PagesController:
use App\Http\Controllers\Controller;
Then included the following code in routes (web.php)
use App\Http\Controllers\PagesController;
Route::get('/', [PagesController::class,'index']);
Laravel 8 is not a namespace prefix for your route groups where your routes are loaded.
"In previous releases of Laravel, the RouteServiceProvider contained a $namespace property. This property's value would automatically be prefixed onto controller route definitions and calls to the action helper / URL::action method. In Laravel 8.x, this property is null by default. This means that no automatic namespace prefixing will be done by Laravel."
When the namespace prefix is ​​not used, you must use the fully qualified class name for your controllers when referring to them in your ways.
use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index']); // or
Route::get('/users', 'App\Http\Controllers\UserController#index'); If
you prefer the old way: App\Providers\RouteServiceProvider:
public function boot() {
...
Route::prefix('api')
->middleware('api')
->namespace('App\Http\Controllers') // <---------
->group(base_path('routes/api.php'));
... }
Do this for any route groups you want a declared namespace for.
The $namespace property:
Release Notes refer to the $namespace property to be set on your RouteServiceProvider in the Release notes and commented in your RouteServiceProvider this does not have any effect on your routes. It is currently only for adding a namespace prefix for generating URLs to actions. So you can set this variable, but it does not add these namespace prefixes, you need to make sure that you are using this variable when adding namespace in the way groups.
information is now an update guide
Laravel 8.x Docs - Upgrade Guide - Routing
With what the Upgrade Guide is showing the important part is that you are defining a namespace on your routes groups. Setting the $namespace variable by itself only helps in generating URLs to actions.
Again, and I can't stress this enough, the important part is setting the namespace for the route groups, which they just happen to be doing by referencing the member variable $namespace directly in the example.
uncomment:
you can uncomment the protected $namespace member variable in the RouteServiceProvider to go back to the old way, as the route groups are setup to use this member variable for the namespace for the groups.
// protected $namespace = 'App\\Http\\Controllers';
The only reason uncommenting that would add the namespace prefix to the Controllers assigned to the routes is because the route groups are setup to use this variable as the namespace:
<?php
namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
/**
* The path to the "home" route for your application.
*
* This is used by Laravel authentication to redirect users after login.
*
* #var string
*/
public const HOME = '/home';
/**
* The controller namespace for the application.
*
* When present, controller route declarations will automatically be prefixed with this namespace.
*
* #var string|null
*/
**protected $namespace = 'App\\Http\\Controllers';**
/**
* Define your route model bindings, pattern filters, etc.
*
* #return void
*/
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
});
}
/**
* Configure the rate limiters for the application.
*
* #return void
*/
protected function configureRateLimiting()
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
});
}
}

Laravel phpunit api return 405

I can not test the api with phpunit testing. I have created a testcase and a test route. But it gives me an error like Expected status code 200 but received 405.
My User controller test:-
<?php
namespace Tests\Feature\API\Medical\V1;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use App\User;
class UserControllerTest extends TestCase
{
/**
* A basic test example.
*
* #return void
*/
public function testLogin()
{
$user = User::find(1);
$response = $this->actingAs($user,'api')->json('POST','/api/test');
$response->assertStatus(200);
}
}
I have not done anything to testCase base class.
My api routes:-
<?php
use Illuminate\Http\Request;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::post('/test',function(){
return response()->json([
'success'=>true
]);
});
But this route is working on postman. When i change http method to GET it gives me my default route on routes/web.php. How to get my actual json to my testcase? thanks in advance.
I faced the same problem.
The project was raised in docker. In the .env file, you need to write:
APP_URL=http://localhost

API Routing Laravel 5.5

I have basic controller, where I want it to receive any json request. Am new to api routing. I get Sorry No Page Found When I use POST MAN. First I tested it on GET and made it call a simple return but throws the error."Sorry, the page you are looking for could not be found."
I removed the api prefix in the RouteServiceProvider.php and to no success.I put my demo controller
Routing api.php
<?php
use Illuminate\Http\Request;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::get('/test_api/v1', 'TestController#formCheck');
TestController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TestController extends Controller
{
public function formCheck(){
return "YES !!!";
}
public function formPost(Request $request)
{
$formData = $request->all();
return response()->json($formData, 201);
}
}
In the app/Providers/RouteServiceProvider.php.
Remove prefix('api') & it shuld look like this.
protected function mapApiRoutes()
{
Route::middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}

Upgrade from laravel 5 to laravel 5.5 caused an error Argument 1 passed to App\Exceptions\Handler::report()

We are trying to upgrade our laravel 5.0 project to the latest version of laravel (laravel 5.5 would be also fine) to support php7.1. When we are running composer install laravel gives the error below:
[Symfony\Component\Debug\Exception\FatalErrorException]
Uncaught TypeError: Argument 1 passed to App\Exceptions\Handler::report() must be an instance of Exception, instanc
e of Error given, called in C:\xampp7\htdocs\V.E.K. Lexmond\vendor\laravel\framework\src\Illuminate\Foundation\Boot
strap\HandleExceptions.php on line 73 and defined in C:\xampp7\htdocs\V.E.K. Lexmond\app\Exceptions\Handler.php:25
Stack trace:
#0 C:\xampp7\htdocs\V.E.K. Lexmond\vendor\laravel\framework\src\Illuminate\Foundation\Bootstrap\HandleExceptions.ph
p(73): App\Exceptions\Handler->report(Object(Error))
#1 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleException(Object(Error))
#2 {main}
thrown
What would be the reason of the this error? We hope anyone got a solution for our problem.
Thank you in advance!
WeTalkive
Can you post what you have in bootstrap/app.php?
also check if you have this in that file
$app->singleton(
Illuminate\Contracts\Debug\ExceptionHandler::class,
App\Exceptions\Handler::class
);
Handler.php
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler {
/**
* A list of the exception types that should not be reported.
*
* #var array
*/
protected $dontReport = [
'Symfony\Component\HttpKernel\Exception\HttpException'
];
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* #param \Exception $e
* #return void
*/
public function report(Exception $e)
{
return parent::report($e);
}
/**
* Render an exception into an HTTP response.
*
* #param \Illuminate\Http\Request $request
* #param \Exception $e
* #return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
return parent::render($request, $e);
}
}
<?php
/*
|--------------------------------------------------------------------------
| Create The Application
|--------------------------------------------------------------------------
|
| The first thing we will do is create a new Laravel application instance
| which serves as the "glue" for all the components of Laravel, and is
| the IoC container for the system binding all of the various parts.
|
*/
$app = new Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
/*
|--------------------------------------------------------------------------
| Bind Important Interfaces
|--------------------------------------------------------------------------
|
| Next, we need to bind some important interfaces into the container so
| we will be able to resolve them when needed. The kernels serve the
| incoming requests to this application from both the web and CLI.
|
*/
$app->singleton(
'Illuminate\Contracts\Http\Kernel',
'App\Http\Kernel'
);
$app->singleton(
'Illuminate\Contracts\Console\Kernel',
'App\Console\Kernel'
);
$app->singleton(
'Illuminate\Contracts\Debug\ExceptionHandler',
'App\Exceptions\Handler'
);
/*
|--------------------------------------------------------------------------
| Return The Application
|--------------------------------------------------------------------------
|
| This script returns the application instance. The instance is given to
| the calling script so we can separate the building of the instances
| from the actual running of the application and sending responses.
|
*/
return $app;

Undefined class Socialite in Spark Laravel 5.4

I'm new to Laravel and Spark trying to figure out how/where I should add my new Controllers and add Socialite.
In my providers I added
Laravel\Socialite\SocialiteServiceProvider::class,
In my aliases I added
'Socialite' => Laravel\Socialite\Facades\Socialite::class,
Here's what my app/HTTP/Controllers/Auth/LoginController class looks like
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Socialite;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
/**
* Redirect the user to the GitHub authentication page.
*
* #return Response
*/
public function redirectToProvider()
{
return Socialite::with('github')->redirect();
}
/**
* Obtain the user information from GitHub.
*
* #return Response
*/
public function handleProviderCallback()
{
$user = Socialite::driver('github')->user();
// $user->token;
}
}
I get undefined class Socialite when I add use Socialite;
I tried composer dump-autoload and php artisan config:clear but nothing is working. Am I doing something wrong?
I'm using Laravel 5.4 and Socialite 3.0
Thanks!
php artisan clear-compiled
composer dump-autoload
php artisan optimize
This will clear the current compiled files, update the classes it needs and then write them back out so you don't have to do it again.

Categories