I'm trying to edit the main Authenticate.php middleware, but when I add the following, I get an error
app.app has redirected you too many times
My intent here is to edit the auth middleware to check if the user has a username. This would prevent someone from exiting the registration page and then simply going into a secure portion of the website.
Auth Middleware:
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('/');
}
}
// This is the modified portion. Check for a username, if one is found, complete
the request, otherwise redirect back to the oauth page.
if (Auth::user()->username)
{
return $next($request);
}
return redirect()->route('oauth.oauth')->with('user' , Auth::user()->id);
}
You are creating a circular reference by using the auth middleware to redirect them to your oauth page when Auth::user()->username isn't present.
They are hitting the oauth page and then failing that check and so being constantly redirected to that page.
The best thing to do would be to split this out in the new middleware, but given you don't want to do this you could check the URL that they are hitting and make an exclusion based on this.
For example:
Add use Request; up the top and then in the body of your middleware add the below:
if (Request::path() == 'your/oauth/path')
{
return $next($request);
}
So it could fit in like this:
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('/');
}
}
// This is the modified portion. Check for a username, if one is found, complete
the request, otherwise redirect back to the oauth page.
if (Auth::user()->username)
{
return $next($request);
}
if (Request::path() == 'your/oauth/path')
{
return $next($request);
}
return redirect()->route('oauth.oauth')->with('user' , Auth::user()->id);
}
Just replace the 'your/oauth/path' with the actual path. That example would look like this as a full url www.example.com/your/oauth/path
Related
I have created a custom auth controller for recognising unauthorized user and redirect them to login path. If logged in the middlewre is working absolutely fine, but showing error if not logged in. Here is my code
Middleware:
class CheckUserAuthenticated
{
public function handle($request, Closure $next)
{
if(auth()->check()) {
$user_id = auth()->user()->id;
define('authenticated_user_id' ,$user_id);
return $next($request);
}
return redirect('login'); // this code is not working
}
}
Error:
try this hope it help
public function handle($request, Closure $next)
{
if(auth()->check()) {
$user_id = auth()->user()->id;
define('authenticated_user_id' ,$user_id);
return $next($request);
}
return redirect('/login'); OR return redirect(route('login'));
}
class CheckUserAuthenticated
{
public function handle($request, Closure $next)
{
if(auth()->check()) {
$user_id = auth()->user()->id;
define('authenticated_user_id' ,$user_id);
return $next($request);
}
// return redirect('login'); // this code is not working
return redirect()->guest('/login');
}
}
redirect()->guest() will redirect if there is no authenticated user.
Example: If an authenticated user is logged in, it won't redirect them as they aren't a guest. If a user isn't logged in, the redirect will happen.
The issue is in circular routing, you are calling from one route, and then return to the same route from the middleware, so your request never reaches the endpoint.
if you call middleware on the...
Route::get('login')->middleware('auth);
...then middleware can not route to 'login' on the fail...
return redirect('login');
... because it will create the loop that never ends. The middleware should reroute to something else, or be placed on other route like 'admin'...
You probably have the middleware on the 'login', that creates the loop, just remove it.
I am trying to protect a route using two middle-wares so that both expert and user can access the same route but as soon a user tries to access the route he is logged out.
I had created two middle-wares for expert and user and protect the route using these middle-wares.
Web.php
Route::group(['middleware' => ['expert','user']], function () {
Route::post('/showForm','UserController#showFormFilled');
});
User Middle ware
public function handle($request, Closure $next)
{
//////////////////// check if user is logged in ///////////////////
if(Auth::check())
{
////////////////// check user role id //////////////////////////
if(auth()->user()->role_id == 3)
{
return $next($request);
}
else if (auth()->user()->role_id==2)
{
return redirect('/expert');
}
}
else
{
return redirect('/login');
}
}
Expert Middle ware
public function handle($request, Closure $next)
{
if(Auth::check()){
if(auth()->user()->role_id == 2)
return $next($request);
else if (auth()->user()->role_id==3)
return redirect('/dashboard');
}
else {
return redirect('/login');
}
}
Both the users should be able to access the same route.
#hamzahummam - there is no way to achieve what you are looking for using the above separate-middlware-for-each-type method. Each middleware prematurely redirects [either to /dashboard or to /expert etc] the request without allowing it to passthrough other middleware. Best would be to use a third-party package that provides a more comprehensive and fine-grained access control [example: https://github.com/Zizaco/entrust]
If that's not an option, the best case would be to implement a single middleware and pass the role as parameter. See: Laravel Middleware Parameters
A minimal example would look like:
public function handle($request, Closure $next, $role)
{
// Assuming Auth::check() passes
$roleId = auth()->user()->role_id;
if ($roleId == 2 && strpos($role, 'expert') !== false) {
// Logged in user is `expert` and route allows `expert` access
return $next($request);
} else if ($roleId == 3 && strpos($role, 'user') !== false) {
// Logged in user is `user` and route allows `user` access
return $next($request);
} // and so on...
// Handle failures here
if ($roleId == 2 && strpos($role, 'expert') === false) {
// an `expert` is trying to access route that can't be accessed
return redirect('/expert-dashboard');
} // and so on...
}
You'd define routes as:
Route::group(['middleware' => ['new_middleware:expert,user' ]], function () {
Route::post('/showForm','UserController#showFormFilled');
});
Hope this helps.
i have a problem with my middleware. when i login as admin, it's working fine and redirect to /Admin/home same as Operator (i have 2 user, Admin & Operator). The problem is when i hit url as example : /Operator/home as Admin role, it can access it. And that's the problem.
I'have create a new middleware CheckMiddleware, and registered to kernel in array $routeMiddleware as checkMiddleware:
public function handle($request, Closure $next)
{
$user = $request->user();
if ($user) {
if ($user->isAdmin()) {
return $next($request);
}elseif($user->isOperator()){
return $next($request);
}
}
return dd('Forbidden page. you have to login as admin/operator');
}
In the route :
Route::group(['prefix'=>'Admin' ,'middleware' => 'checkMiddleware'], function() {
Route::get('/home', 'HomeController#index')->name('homeAdmin');
});
Route::group(['prefix'=>'Operator' ,'middleware' => 'checkMiddleware'], function() {
Route::get('/home', 'HomeController#index')->name('homeAdmin');
});
Auth::routes();
in User model :
public function isAdmin(){
if ($this->role_id === 1) {
return true;
}
return false;
}
public function isOperator(){
if ($this->role_id === 2) {
return true;
}
return false;
}
What i want is, Admin cannot access Operator and Operator Cannot Access Admin.
if this is not clear, tell me what file you want to see.
The problem is if user is admin then accept request and user is operator still accept request. That code below
if ($user->isAdmin()) {
return $next($request);
}elseif($user->isOperator()){
return $next($request);
}
For simple solution, just create two middleware for admin and operator. Then apply admin middleware for route (group) need admin role, and apply operator middleware for route (group) need operator role.
If you have some route allow admin and operator role access, just add both to that route.
UPDATE
If you want to use 1 middleware, do like this :
if ($user->isAdmin() && $request->route()->getPrefix() == 'admin') {
return $next($request);
}
if ($user->isOperator() && $request->route()->getPrefix() == 'operator') {
return $next($request);
}
return abort(401) // OR SOME ROUTE YOU WANT
In my app, a post author can set an otherwise public post to private. If an unauthenticated user tries to visit that post, they will be prompted to login.
After they authenticate, I want to redirect them back to the original post URL, so they can read that private post.
This behavior is normally handled by Laravel's default auth middleware. However, because the posts are often public, I can't use that in this case.
Here's my current, non-functioning middleware:
public function handle($request, Closure $next)
{
$post = $request->route('post');
if ($post->isPrivate()) {
$request->session()->setPreviousUrl($request->url());
return redirect()->guest('login');
}
return $next($request);
}
My hope is that I can set a custom URL to redirect to (/posts/{id}). However, when I try to login, I'm redirected to my default $redirectTo property (/dashboard).
Is this something that's feasible? Am I even thinking about this in the correct way?
#adam, thanks for the assist!
For anyone else looking, here's my final code:
Middleware:
public function handle($request, Closure $next)
{
if (auth()->check()) {
return $next($request);
}
$post = $request->route('post');
if ($post->isPrivate()) {
$request->session()->setPreviousUrl($request->path());
return redirect()->guest('login');
}
return $next($request);
}
LoginController:
protected function authenticated(Request $request, $user)
{
if ($request->session()->has('url.intended')) {
return redirect($request->session()->get('url.intended'));
}
}
I am using Laravel 5.2 and I have Authenticate.php file in:
\vendor\laravel\framework\src\Illuminate\Auth\Middleware
I need to authenticate my user so that, the user can't access the logged in page by just writing it in URL. How to do it?
When I searched, the solutions were for the Authenticate file which was in Middleware folder inside Http, which was a little different.
Please tell me how to do it. I tried:
if(Auth::guard($guard) -> guest()){
if ($request -> ajax()){
return response['Unauthorized',401];
} else{
return redirect() -> guest('login');
}
}
return $next($request);
}
}
How to do it? please tell me options. Any suggestion is invited.
And, Thank you in advance... :)
The solutions you found while searching are correct, you should actually edit your middlewares inside app/Http/Middleware if you checked out the documentation here, the right way to do it is:
You have to update this middleware app/Http/Middleware/RedirectIfAuthenticated.php which has this function
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/admin');
}
return $next($request);
}
What you can do in your case, you can use the same if clause in your current handle function, so it looks like this:
if (Auth::guard($guard)->check()) {
return redirect('/admin');
}
if (Auth::guard($guard)->guest()) {
if ($request->ajax()) {
return response['Unauthorized',401];
} else {
return redirect()->guest('login');
}
}
return $next($request);
Put all the routes that only the logged in users can access into Auth Middleware group:
Route::group(['middleware' => ['auth']], function () {
// Routes here
});