Laravel Middleware change response content - laravel-5

For my application I am having multiple user roles and a custom maintenance mode. If the site is in maintenance mode, then depending on the user's role will limit their access to certain pages.
So when "normal" users access the forums, they should instead see a different view saying that the site is in maintenance mode; whereas when "admin" users access the forums they should be able to see the forums.
public function handle($request, Closure $next) {
if(Auth::user()->role->maintenance_mode != 1) {
// They do not have access during maintenance mode,
// so change the response to show a different view.
}
// They do have access during maintenance mode,
// so continue the request.
return $next($request);
}
Is it possible to have the same route (e.g. /forums) but to show a different view, changed by the middleware.

It is possible, yes, however each middleware calls $next($request) which may point to another middleware before the route, therefore returning a view may not be the best idea. If you do want to do it, then you need to do something like: return new Response(view('maintanance')); and don't forget to include use Illuminate\Http\Response; in the header of your Middleware class.
In your case, what I would do is have a route that returns a view such as /maintainance (preferably with a name) and then in the middleware, return a redirect to the route return redirect()->route('maintanance'); within the if.
You could also throw a HttpException with the status code of 503 to have the application invoke Laravel's built in maintenance mode within that first if.

Related

Strategy to make the website open for public via Route or User trigger

I have developed a Web App for a non profit entity. I am currently in staging mode. In-order for some routes to make accessible i have created a middleware.
Problem : The administration wants the Head of the Institution to make the website public. If so, what would be the best approach ?
My middleware
public function handle(Request $request, Closure $next)
{
if(App::environment('local')) {
return $next($request);
} else {
return new Response(view('layouts.coming-soon'));
}
}
//routes
Route::middleware(['domain_block'])->domain('example.' . $tld)->group(function() {
Route::get('/', [PagesController::class, 'showHomepage'])->name('homepage');
Route::get('about-us',[PagesController::class, 'aboutUs'])->name('about_us');
});
I can understand if i store a value in a config via Config::set('custom.my_val', 'mysinglelue'); , the request doesn't update from the config value until i clear the config cache.
Edit:
This plan is only to show people that it launched realtime and people can start using the web app. Later on i can remove the middleware.
When an user visits the webapp, the users sees all the routes except what is in the domain_block middleware. As this launching is going to happen while on a zoom meeting, people will expect to see the page right after the head of institution opens the page to the public. Users will reload the page to see the live page.
I am using Beanstalk for my deployment and it takes some time to build. That is why i wanted to go with a different approach so later on i could remove the middleware

Laravel 5.1 use session to restrict direct access using urls users based on user role

I have 2 laravel projects, 1 for the front end where i m using html css angularjs. The second for api controllers. I call using http post and get the api controllers functions using angularjs to get content data.
In the front end i have a menu this menu appears differently based on user role, if admin or no.
This is done. My problem is the access for views using the url in the browser.
So I have a query where I get for each user what modules in the menu can he see. Now I'm putting the result in Laravel session.
$menu = DB::select menu by user id ... //Getting menu query based on user if admin or no
session(["menu" => $menu);
return session('menu');
I'm getting the results and the menu is showing good in the website based on the logged user if he s admin or no.
Now, to solve the direct url access issue, I want to use this session and compare the url to this session, if the url exists in the session i will let him access, if no i will redirect him to somewhere.
any idea?
I would strongly suggest looking at the Laravel documentation on Authorization before going too far down a custom implementation:
https://laravel.com/docs/5.1/authorization
Without knowing more about how your front-end and back-end applications interact with each other, it is a little difficult to get into speciifics but i shall do my best.
Each page returned by Laravel has access to a Request object which contains information about the request which returned the page. You can access this Request and its assocaited Route using Laravels helper functions (if you are not passing it to the view already). The getPrefix() method will return the root relative url which you can then use as you see fit. For example:
// Return and store the URL as a string
$url = request()->route()->getPrefix();
// Check your session for the URL/s you want to allow and compare to the stored URL
if (session()->get('URL') == $url) {
// User is allowed access to the page
// Do something ...
} else {
// User is not allowed access to this page
// Redirect back or to a route of your choice
return redirect()->back();
}
I hope this gives you some ideas, good luck!

Is it possible to get Laravel user data from Vue JS?

i have a Laravel 5.4 application where i do all Authentication based logic through PHP and then redirect the user to a catchAll route when they are authenticated, and let VueRouter take it from there...
I'd like to also use Entrust because my app will have several types of users and some elements (like an Edit User button) will only be visible to some user Roles.
I might also want to implement specific permissions, like some Admins can edit user Permissions, while others do not.
The issue is, alright i'm in Javascript territory now, so how do i know what my current Auth user is? Setting a global JS variable for Auth::user doesn't seem like a good idea to me.
Perhaps i would instead pass just an ID, but how exactly without making it globally visible as a window variable?
I think you may create an auth/check API call, like this:
protected function check()
{
if(Auth::guard('api')->check()) {
return Auth::guard('api')->user();
}
return ['success' => false];;
}
And then get current user with this call.

How to use intended function in Laravel

I need to register in a tournament with the URL:
http://laravel.dev/tournaments/1/register/
This URL is in the middleware 'auth', so if the user is not logged, he is redirected to login / page.
What I need is to redirect to
http://laravel.dev/tournaments/1/register/
After login.
In my routes.php, I have:
Route::get('tournaments/{tournamentId}/register', 'TournamentController#register');
I was told to use
redirect()->intended
but I don't know how to do it.
In the general case, User will be redirected to /admin, but in this case, I want him to keep doing his main action ( Register tournament)...
I'm using the built in trait for login, so I checked what system do when login and it is already using this function:
protected function handleUserWasAuthenticated(Request $request, $throttles)
{
if ($throttles) {
$this->clearLoginAttempts($request);
}
if (method_exists($this, 'authenticated')) {
return $this->authenticated($request, Auth::guard($this->getGuard())->user());
}
return redirect()->intended($this->redirectPath());
}
Thing is it will redirect me to a default path, not a dynamic one...
You should to know different between Redirect To and Redirect Intended
Redirect Intended: redirects the user to where they were originally going
Redirect To: Redirect the user to the page **YOU** specify them to go.
Things to check:
Use your browser's inspect element network feature to trace redirects - there may be several, which could help clear up confusion.
The intended() method requires a call to guest() when redirecting previous to the former. This happens in the Authenticate middleware, but
if you're using some other middleware (such as a middleware to catch and redirect admins to an admin area), this might be triggering first and redirecting without using guest().
Does your controller using the AuthenticatesUsers trait implement the authenticated method? If so this will be returned instead of redirect()->intended().

Laravel 5 - Is there a way to use built-in authentication but disable registration?

I am building an administrative back-end and thus need to hide public user registration. It appears that if you want to use the built-in Illuminate authentication you need to add
use AuthenticatesAndRegistersUsers to your controller definition. This trait is defined here.
It appears as if it is impossible to disable registration if you want to use the built-in auth handlers... can someone show me wrong?
I'm using Laravel 5.2+ and I found that if you remove the Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers and use just Illuminate\Foundation\Auth\AuthenticatesUsers does the trick too.
Though /register is still accessible and will throw a fatal error.
This page talks about overriding the auth controller. Its worth a read, at a basic level it seems you can add the following lines to app\Http\Controllers\Auth\AuthController.php :
public function getRegister() {
return redirect('/');
}
public function postRegister() {
return redirect('/');
}
So if a user accesses the registration url it will redirect them away to a place of your choosing.
You can have your own form of registration. The only thing Laravel does is make it easy to authenticate on a users table because they create the model, build the db schema for users and provide helper methods to authenticate on that model/table.
You don't have to have a view hitting the registration page... But if you want to use the built in auth you still need to use (or set) a Model and a driver for database connections.
You can just remove that view and/or controller method from the route that links to the registration view and create your own (or seed the database manually).
But, no, you cannot forgo using Eloquent, and the User model and expect to use built in auth. Built in authentication requires that you specify settings in /config/auth.php. You may specific a different model (other than User) and you may specify a different table, but you cannot forgo the configuration completely.
Laravel is very customizable though, so you can achieve what you are looking to do... plus why not use Eloquent, it's nice.
Based on #shoo's answer, working with Laravel 5.2
Add the following lines to app\Http\Controllers\Auth\AuthController.php :
public function showRegistrationForm() {
return redirect('/');
}
public function register() {
return redirect('/');
}

Resources