I set locale in middleware using session variable and it is working perfectly except 404 page. As I understood, neither session variables nor middleware works in exception handler. Here is my code:
Route:
Route::get('setlocale/{locale}', function ($locale) {
if (in_array($locale, \Config::get('app.locales'))) {
Session::put('locale', $locale);
}
return redirect()->back();
})->name('lang.switch');
Middleware:
class Language
{
public function handle($request, Closure $next)
{
$raw_locale = Session::get('locale');
if (in_array($raw_locale, Config::get('app.locales'))) {
$locale = $raw_locale;
} else $locale = Config::get('app.locale');
App::setLocale($locale);
return $next($request);
}
}
Any ideas?
Related
I can't use localization prefix because of my client's needs. I'm trying to store locale data into session and group my routes based on that 'locale'. But i cant access session data inside web.php.
$locale = Session::get('locale');
if($locale == 'tr') {
Route::get('/kurumsal/{slug}', 'App\Http\Controllers\CorporateController#index')->name('corporate');
} elseif ($locale == 'eng){
Route::get('/corporate/{slug}', 'App\Http\Controllers\CorporateController#index')->name('corporate');
}
LanguageController middleware
class LanguageController extends Controller
{
public function index($locale = ''){
if ($locale == '') {
Session::put('locale', 'eng');
} else {
Session::put('locale', $locale);
}
return redirect()->back();
}
}
You don't need to conditionally set routes if there's no conflicts.
The following works just fine:
Route::get('/kurumsal/{slug}', 'App\Http\Controllers\CorporateController#index')->name('corporate');
Route::get('/corporate/{slug}', 'App\Http\Controllers\CorporateController#index')->name('corporate');
If you want to restrict non-localised routes from being accessed then you do need session access but you can have that via middleware e.g.:
class LocaleRestricted {
public function handle($request, $next, ...$localesAllowed) {
if (!in_array(Session::get('locale'), $localesAllowed)) {
abort(404, 'This route is not available for this locale');
}
return $next($request);
}
}
You then need to register this locale in your app/Http/Kernel.php:
// ...
protected $routeMiddleware = [
// ...
'locale_restricted' => LocaleRestricted::class
];
Then you can use it as:
$locale = Session::get('locale');
Route::middleware('locale_restricted:tr')->group(function () {
Route::get('/kurumsal/{slug}', 'App\Http\Controllers\CorporateController#index')->name('corporate');
});
Route::middleware('locale_restricted:eng')->group(function () {
Route::get('/corporate/{slug}', 'App\Http\Controllers\CorporateController#index')->name('corporate');
});
For Get Data from session you can use
$value = $request->session()->get('your-key-name');
But I'm not sure It works in Web.php or not..!! But you can use this one in Controller, Middelware etc many more places.
For More Details See Laravel Official Documentation
I have a problem when I want to pass data to the view via the middleware to count the number of users. when not using middleware, variable from controller get to the view.
my HomeController.php
public function index()
{
$count = User::count();
return view('admin.Dashboard', compact($count);
}
my Middleware
public function handle(Request $request, Closure $next)
{
if ($request->user() && $request->user()->role == 'admin') {
return response()->view('admin.Dashboard');
} else {
return response()->view('member.dashboard');
}
return $next($request);
}
the $count variable if using middleware in route not passed to the view
my web.php
Auth::routes(['verify' => true]);
Route::get('/dashboard', 'HomeController#index')->middleware('verified', 'cekrole')->name('home');
In your middleware you are returning response (a view), so
return $next($request);
will never be executed, so neither will your controller.
User call /dashboard > Your middleware is called > if it's an admin you are returning admin.Dashboard, else member.dashboard.
But you never execute code in your Controller.
As a quick fix you could replace your Middleware by :
public function handle(Request $request, Closure $next)
{
if ($request->user() && $request->user()->role == 'admin') {
$count = User::count();
return view('admin.Dashboard', compact('count'));
}
return response()->view('member.dashboard');
}
or make those test (admin/not admin) in your controller
I'm new to laravel I have created middleware for my each role but when I add it to my route it won't work.
If I add single middleware to my route it works fine but when I add second and third one It will not work.
It won't shows the route to authorized user it redirect it to home,
My User Model:
public function IsAdmin()
{
if($this->role_id =='1')
{
return true;
}
else
{
return false;
}
}
public function IsManager()
{
if($this->role_id =='2')
{
return true;
}
else
{
return false;
}
}
public function IsUser()
{
if($this->role_id =='3')
{
return true;
}
else
{
return false;
}
}
My Kernal:
'IsAdmin' => \App\Http\Middleware\IsAdmin::class,
'IsManager' => \App\Http\Middleware\IsManager::class,
'IsUser' => \App\Http\Middleware\IsUser::class,
My IsAdmin Middlewares:
public function handle($request, Closure $next)
{
$user =Auth::User();
if(!$user->IsAdmin())
{
return redirect('stock');
}
return $next($request);
}
My IsManager
public function handle($request, Closure $next)
{
$user =Auth::User();
if(!$user->IsManager())
{
return redirect('stock');
}
return $next($request);
}
and IsUser
public function handle($request, Closure $next)
{
$user =Auth::User();
if(!$user->IsUser())
{
return redirect('stock');
}
return $next($request);
}
and finally my Route
Route::get('approv',['middleware'=>['IsManager','IsAdmin'],function(){
return view('approv');
}]);
This will not work as you'd expect. All middleware need to pass in order for the request to be processed which means that your user will need to be both a manager and an admin at the same time which based on your setup is impossible.
You can get around this (kind of) by making a different kind of middleware:
Kernel:
'roles' => \App\Http\Middleware\Roles::class,
And the Roles middleware:
class Roles {
private function checkRole($role) {
switch ($role) {
case 'user': return \Auth::user()->IsUser();
case 'manager': return \Auth::user()->IsManager();
case 'admin': return \Auth::user()->IsAdmin();
}
return false;
}
public function handle($request, Closure $next, ...$roles)
{
foreach ($roles as $role) {
if ($this->checkRole($role)) {
//At least one role passes
return $next($request);
}
}
//All checks failed so user does not have any of the required roles
return redirect('stock');
}
}
Then to use this you simply do:
Route::get('approv',['middleware'=>['roles:manager,admin'],function(){
return view('approv');
}]);
This works because Laravel Middleware support parameters. You can pass parameters as a comma separated list of strings where you declare the middleware. In this case this was done as roles:manager,admin
Laravel will then send these parameters as additional parameters in the handle method. These can be accessed using PHPs syntax for variadic arguments. In this particular case it's by using the array spread operator. This is documented as an example in the function arguments section of the PHP manual.
Note that this is actually equivalent to saying :
public function handle($request, Closure $next, $role1=null, $role2=null, $role3=null)
but using the spread operator is much more convenient since ...$roles would be an array which contains only the roles that were passed in the middleware.
I am trying to protect my routes in Laravel 5.3. I am using below codes
Route::get('profile', function () {
// Only authenticated users may enter...
})->middleware('auth');
If I try to browse /profile in logout situation it redirects me to /login route. But I would like to redirect it to / route.
How can I do that ??
On laravel 5.3 it's on Exceptions directory. Go to App\Exceptions\Handler.php and on the bottom change the code:
return redirect()->guest('/');
change file app\Middleware\RedirectIfAuthenticated.php
and edit this line:
return redirect('/login');
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/');
}
return $next($request);
}
Please write this function in this file app\Middleware\RedirectIfAuthenticated.php
You can try
Route::group(['middleware'=>'web'],function (){
Route::Auth();
Route::get('/home', 'HomeController#index');});
and change app\Middleware\RedirectIfAuthenticated.php
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/');
}
return $next($request);
}
I am using Sentinel to authenticate users and as the auth Middleware.
Middleware code:
public function handle($request, Closure $next)
{
var_dump(Sentinel::guest()); // prints false
if (Sentinel::guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('/login');
}
}
return $next($request);
}
Controller code:
public function getAccount() {
var_dump(Sentinel::guest()); // prints true
return Sentinel::getUser();
}
routes.php
Route::group(['middleware' => ['auth']], function () {
Route::get('api/v1/temp/users/account', 'App\Http\Controllers\UsersController#getAccount');
}
Then if i browse to api/v1/temp/users/account the var_dump() in the Middleware is printing false, while the var_dump() inside the controller is printing true which seems a nonsense.
What's wrong?
It turned out i was using the native facade instead of the Laravel facade Cartalyst\Sentinel\Laravel\Facades\Sentinel. That fixed.