I want to make authentication for API requests coming from mobile users.
I followed this
and made api_key column inside users table.
I also created middleware:
public function handle($request, Closure $next)
{
$token = $request->bearerToken();
return $next($token);
}
What I want is to get bearer token from header and check it against user table.
How to achieve this?
Append the auth:api middleware to any route or group of routes and the Bearer token will be checked automatically for you without a custom middleware
Route::get('url', 'controller#method')->middleware('auth:api');
But to answer the question, here's what you can do (still not recommended but works)
<?php
namespace App\Http\Middleware;
use Closure;
class ApiAuthentication
{
public function handle($request, Closure $next)
{
$token = $request->bearerToken();
$user = \App\User::where('api_token', $token)->first();
if ($user) {
auth()->login($user);
return $next($request);
}
return response([
'message' => 'Unauthenticated'
], 403);
}
}
Register the middleware in App\Http\Kernel
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
// Here for example
'custom_auth' => \App\Http\Middleware\ApiAuthentication::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
And protect a route with that middleware name
Route::get('/', function () {
// Return authenticated user model object serialized to json
return auth()->user();
})->middleware('custom_auth');
Result
I would recommend laravel/passport as it is much secure and easier.
Click Here.
Related
I am using Laravel 8 and when i redirect a route from middleware i am facing issue
ERR_TOO_MANY_REDIRECTS. I am verifying user with firebase otp and set cookie if otp verify then i want to redirect register page if user not exist in db. I have create middleware and check if cookie set then redirect to register route.
public function handle(Request $request, Closure $next)
{
if (Cookie::get('otpVerified')){
return redirect()->route('register');
}
return $next($request);
}
after that i am facing this issue
enter image description here
my route file is
Route::get('/register', [RegisterController::class, 'register'])->name('register_user');
Auth::routes();
Route::group(['middleware' => 'otpVerify'], function (){
Route::get('/404', [\App\Http\Controllers\ErrorController::class, 'notFound'])->name('404');
Route::get('/', [\App\Http\Controllers\Dashboard\DashboardController::class, 'index'])->name('dashboard');
});
How can i fix it. My kernel file is
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
and
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'otpVerify' => \App\Http\Middleware\OTPVarification::class,
];
In this section, you must exclude the register root
public function handle(Request $request, Closure $next)
{
if (Cookie::get('otpVerified') && $request->route()->getActionName() !== 'YourRegisterAction'){
return redirect()->route('register');
}
return $next($request);
}
i'm in trouble for 2 days with the laravel auth middlewares.
I have understand how the Auth system work with JWTtoken. In my controller all work fine i got my user login and i can access with Auth::guard->user().
But i have one problem in my middleware Authenticate.php :
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Support\Facades\Auth;
use Closure;
class Authenticate extends Middleware
{
protected function redirectTo($request)
{ dd(
$request->user(),
auth()->id() ?? '?',
Auth::id() ?? '?',
$request->user()->id ?? '?',
auth()->check(),
get_class(auth()->guard())
);
}
}
I try everything i found in multiple post or tutorial, but the result is the same (same time in controller all work user is login) :
null
"?"
"?"
"?"
false
"Tymon\JWTAuth\JWTGuard"
AuthController.php
public function __construct()
{
$this->middleware('auth', ['except' => ['login', 'register']]);
}
public function login(Request $request){
$credentials = $request->only('email', 'password');
if(!$token = $this->guard()->attempt($credentials)){
return response()->json(['error' => "L'email ou le mot de passe ne correspondent pas."]);
}else {
return response()->json([
'token' => $token,
]);
}
}
public function guard()
{
return Auth::guard();
}
And Multiple function me,logout...
Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
//'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
}
I have try to take rules in $middlewareGroups web and past in $middleware, and if i do that is say :
"Call to a member function parameters() on null".
So nothing change my Auth is null.
Thanks a lot if someone can explain me the problem and what i do wrong !
EDIT :
api.php
Route::group(['prefix' => 'auth', 'namespace' => 'Auth'], function ($router) {
Route::post('/inscription', 'AuthController#register');
Route::post('/connexion', 'AuthController#login');
Route::get('/logout', 'AuthController#logout');
Route::get('/me', 'AuthController#me');
Route::get('/isAdmin', 'AuthController#isAdmin');
});
Solution not found :(
Authenticate.php
public function handle($request, Closure $next, ...$guards)
{
$this->authenticate($request, $guards);
$user = $this->auth->user();
...do your thing....
Kernel.php
protected $middlewareGroups = [
'api' => [
\Illuminate\Session\Middleware\StartSession::class,
\AEPlanning\Http\Middleware\VerifyCsrfToken::class,
You will get user only after successful login
Hi I am working on laravel project , I have to check about user's permission when he trying to access one page , my problem is after I created Permission middle ware , and add it in the kernel.php , it checking about permissions for all route even I did not call it in any route .
I don't want to apply this middleware on all route , just some of it .
this is my permission middleware's code
namespace App\Http\Middleware;
use Closure;
use Session;
use App\Rules;
use Illuminate\Support\Facades\Route;
use URL;
class Permissions
{
public function handle($request, Closure $next) {
$rolename=Session::get('rule_name') ;
$route = $request->path();
$hasPermission = Rules::where('rule_name', 'superadmin')->where('allowed_pages', 'like', '%' . $route . '%') ->first();
if (empty($hasPermission)) {
echo 'Unauthorized.Go Back';
die();
}
}
}
}
and this is my route file
Route::resource('Login', 'LoginController')->name('index','Login');
Route::resource('Backup', 'BackupController')->name('index','Backup');
as you see I did not apply the middleware on these tow route , but the middleware is working with these tow routes
this is my kernel code
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
'Permissions' => \App\Http\Middleware\Permissions::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
I want to run this middleware only by route like this
Route::group(['middleware' => 'permissions'], function () {
Route::resource('Backup', 'BackupController')->name('index','Backup');
}
thank you for advance
best regards
You added your middleware to the middelwareGroup web, wich applies the middleware to every request comming in.
You need to add your middleware to the routes middleware array: docs
// Within App\Http\Kernel Class...
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
...
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
// your own middlewares:
'Permissions' => \App\Http\Middleware\Permissions::class,
];
You can than apply the middleware to specific routes:
Route::resource('Login', 'LoginController')->middleware('Permissions')->name('index','Login');
you added inside web which is default middleware by laravel that's why it's applied in all route.
to register a middleware you need to add in protected $routeMiddleware = [ ] array
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
//custom middlewares:
'Permissions' => \App\Http\Middleware\Permissions::class,
];
then only
Route::group(['middleware' => 'permissions'], function () {
Route::resource('Backup', 'BackupController')->name('index','Backup');
}
it will work
I have used middlewares for many Laravel applications, but this is a stupid situation never happened to me before. The middleware always returns false for Auth::check()
This is routes of User module
<?php
Route::group(['middleware' => 'web', 'namespace' => 'Modules\User\Http\Controllers'], function () {
Route::get('/', 'UserController#index');
Route::get('login', 'LoginController#showLoginForm')->name('login');
Route::post('login', 'LoginController#login');
Route::post('logout', 'LoginController#logout')->name('logout');
});
Route::group(['middleware' => 'admin', 'prefix' => 'user', 'namespace' => 'Modules\User\Http\Controllers'], function () {
Route::get('register', 'RegisterController#showRegistrationForm')->name('register');
Route::post('register', 'RegisterController#register');
});
This is AdminMiddleware inside the User module
<?php
namespace Modules\User\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AdminMiddleware
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
$log = Auth::check();
dd($log);
return $next($request);
}
}
and this is kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'admin' => \Modules\User\Http\Middleware\AdminMiddleware::class
];
But the result of dd($log) is always false. What is wrong here?!!!
You also need to add web middleware to User module routes group.
Because the session starts there.
Just saying, another solution is that you added it to the global middleware stack instead of the web middleware group! (Only add it to web, it can't be both)
please append your middleware address:
\Modules\User\Http\Middleware\AdminMiddleware::class
to
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Modules\User\Http\Middleware\AdminMiddleware::class //this is your middleware.
],
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
you can set your middleware's priority to be loaded after StartSession to be sure it will be loaded after the session starts.
in kernel.php
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Modules\User\Http\Middleware\AdminMiddleware::class
\App\Http\Middleware\Authenticate::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
\App\Http\Middleware\CheckProfileRequiredData::class, // putting CheckProfileRequiredData after Auth priority is required! to perform it's check after auth middleware
\App\Http\Middleware\CheckUserMustPayWithoutAnsweringDietRequiredQuestions::class,
];
I'm trying to pass to all templates current user object like this:
class Controller extends BaseController
{
public function __construct()
{
view()->share('usr', Auth::guard('user'));
}
}
Every controller is extended by Controller. But if i try to dump Auth::guard('user')->user() Laravel returns null, although I am logged in. Moreover when i pass this variable into template, {{ $usr->user() }} returns current user. What I've done wrong?
my config/auth.php
'defaults' => [
'guard' => 'user',
'passwords' => 'users',
],
'guards' => [
'user' => [
'driver' => 'session',
'provider' => 'user',
],
],
'providers' => [
'user' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
],
Kernel.php
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
//\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
my own function to log in:
public function authorizes(Request $request)
{
$this->validate($request, [
'login' => 'required|max:50',
'password' => 'required|max:50'
]);
$credentials = $request->only(['login', 'password' ]);
$remember = $request->get('remember', false) == 1 ? true : false;
if ($this->guard->attempt( $credentials, $remember)) {
$user = $this->guard->user();
$user->last_login = date('Y-m-d H:i:s');
$user->save();
return redirect()->route( 'homepage' )->withSuccess(trans('app.login.success'));
}
return redirect()->back()->withErrors(trans('app.wrong.credentials'));
}
In Laravel 5.3 you should change your controller constructor like so to make this work (assuming you use at least Laravel 5.3.4):
public function __construct()
{
$this->middleware(function ($request, $next) {
view()->share('usr', Auth::guard('user'));
return $next($request);
});
}
You can see this change described in Upgrade guide:
In previous versions of Laravel, you could access session variables or
the authenticated user in your controller's constructor. This was
never intended to be an explicit feature of the framework. In Laravel
5.3, you can't access the session or authenticated user in your controller's constructor because the middleware has not run yet.
As an alternative, you may define a Closure based middleware directly
in your controller's constructor. Before using this feature, make sure
that your application is running Laravel 5.3.4
Try to do this:
view()->share('usr', Auth::user());
Or this:
view()->share('usr', auth()->user());
Frist check if user is logged or not, then share the current user as:
public function __construct()
{
if (auth()->check()) {
$this->currentUser = auth()->user();
View::share('currentUser', $this->currentUser);
} else {
// you can redirect the user to login page.
}
}
In your case there are two things to consider
To get actual user model you should do Auth::guard('user')->user()
Auth::user() is actually not yet initialized when view()->share() is called, see https://github.com/laravel/framework/issues/6130
Therefore you could rather use view composer. In boot method of your AppServiceProvider add:
\View::composer('*', function ($view) {
$view->with('usr', \Auth::guard('user')->user());
});