I'm using Laravel 5.2 and doing all authentication manually. So, although everything works, but I get a token mismatch error and the reason is that I'm not passing my routes through the web middleware in my routes file:
Route::group(['middleware'=>['web']],function (){
Route::get('/', function () {
return view('welcome');
})->name('home');
});
Route::social();
where Route::social(); is
public function social() {
$this->post('/signup',['uses'=>'UserController#postSignUp','as'=>'signup']);
$this->post('/signin',['uses'=>'UserController#postSignIn','as'=>'signin']);
$this->get('/dashboard',function() {
return view('dashboard');
})->middleware('auth');
}
But if I move Route::social(); to the web middleware group, it doesn't count errors and so return empty errors even if there are. How do I get around with it? I want both things!
I've the token field in my form using {!! Form::token() !!}
You are probably manually adding an $error array to your view, the web middleware will do the same thing so this will be overwritten. The web middleware group includes \Illuminate\View\Middleware\ShareErrorsFromSession which creates an error variable in the views with validation errors.
There are two ways to fix this. One is to only include the \App\Http\Middleware\VerifyCsrfToken middleware for this route. The other, wich I would prefer, is to add the route to the web middleware group, but use another name for your array with errors.
Related
We have a large website with many pages. Almost all of them require the user to log in. Instead of specifying "Auth" on every single page, or on every single controller, I would like to set the routes based on if the user is logged in, like this:
// in web.php
if (Auth::isLoggedIn()) {
Route::get('/', function () { return view('pages/dashboard'); });
... lots more
}
The reason I can't do this is because Auth uses sessions, and sessions are not yet initialized in web.php, since it is done as middleware which is not run yet at this point.
I'm using Laravel 8, I believe.
Thanks.
you can group the route that need the user to be logged in, then use auth middleware
for the grouped routes:
Route::middleware(['auth'])->group(function () {
Route::get('/', function () {
//
});
Route::get('/', function () { return view('pages/dashboard'); });
});
Try using Laravel's Route middleware. Route middleware can be used to only allow authenticated users to access a given route.
I started creating a REST API using the lumen framework and wanted to set up a particular behaviour for my GET /user route. Behaviour is the following:
If the request come from an authenticated user (using auth middleware), the method getAllFields from UserController is called and return all the data from the user
If it's not the case, the method get from UserController is called and return some of the data from the user
It seems logic to me to just write it like that in my web.php using a simple middleware:
<?php
$router->group(['middleware' => 'auth'], function () use ($router) {
$router->get('/user/{id}', [
'uses' => 'UserController#getAllFields'
]);
});
$router->get('/user/{id}', [
'uses' => 'UserController#get'
]);
But for some reason, even if the middleware is correct, I always get the response of the second route declaration (that call get()). I precise that if I remove the second route declaration, the one in the middleware work as expected.
Have someone an idea how I can achieve something similar that work?
Router will check if your request matches to any declared route. Middleware will run AFTER that match, so You cannot just return to router and try to find another match.
To fallow Laravel and Routes pattern - You should have single route that will point to method inside controller. Then inside that You can check if user is logged or not and execute getAllFields() from that controller. It will be not much to rewrite since You are currently using UserController in both routes anyway.
web.php
$router->get('/user/{id}', 'UserController#get');
UserController.php
public function get()
{
return auth()->check() ? YourMethodForLogged() : YourMethodForNotLogged();
}
Or if there is not much logic You can keep this in single method.
Also it is good idea to fallow Laravels REST standards (so use show instead of get, "users" instead of "user" etc - read more https://laravel.com/docs/7.x/controllers)
web.php
$router->get('/users/{user}', 'UserController#show');
UserController.php
public function show(User $user)
{
if (auth()->check()) {
//
} else {
//
}
}
To summary - for your needs use Auth inside controller instead of middleware.
To check if user is logged You can use Facade Auth::check() or helper auth()->check(), or opposite Auth::guest() or auth()->guest().
If you are actually using Lumen instead of full Laravel then there is not auth helper by default (You can make own or use package like lumen-helpers) or just keep it simple and use just Facades instead (if You have then enabled in Lumen).
Read more https://laravel.com/docs/7.x/authentication and https://lumen.laravel.com/docs/7.x/authentication
This pattern is against the idea of Laravel's routing. Each route should be defined once.
You can define your route without auth middleware enabled and then define your logic in the controller.
Lately I've been working on a project in Laravel 5.2 and now I'm having problems with sessions not persisting. I've read most of the questions already asked regarding this but everyone has the same answer that I have already tried - applying web middleware.
I've read that there was a new L5.2 update where the web middleware group is already applied by default. I checked my routes with php artisan route:list and I can see that every route has only 1 web middleware applied.
I'm creating session with $request->session()->put('key', 'value') but as soon as I comment that line the session is nowhere to be seen anymore.
Edit
I want to set the session inside a controller when I visit a news page, but I tried it on a simple test route as well. Route where I set this is news/{id} and I want to use it on the front page which is in /
I wish to store recently visited pages in session so I can then show it to the user on the front page.
Session config file I left untouched. So it's using file driver
Here is a tested routes to use for your projects
Please use a middleware instead of the function in the routes file
routes.php
// Only as a demo
// Use a middleware instead
function addToSession ($routeName) {
$visited = session()->get('visited', []);
array_push($visited, $routeName);
session()->put('visited', $visited);
}
Route::get('/', function () {
addToSession('/');
return view('welcome');
});
Route::get('/second', function () {
addToSession('/second');
return view('welcome');
});
Route::get('/third', function () {
addToSession('/third');
return view('welcome');
});
Route::get('/history', function() {
return session()->get('visited');
});
The /history route will return a JSON having the history.
I have my auth doing this on login.
if (Auth::attempt($userdata)) {
dd(Auth::user()); //this shows the user just fine,
//which proves that the auth driver is working.
return redirect()->intended('dashboard');
}
However, after redirecting to the dashboard. It appears the auth isn't persisted. If I do dd(Auth::user()) or even just Auth::check() it returns null.
Here's the route:
Route::group(['middleware' => ['web']], function () {
Route::get('test',function(){
dd(Auth::user()); //returns null
echo Auth::user()->name; // returns Trying to get property of non-object
});
});
What am I doing wrong?
The weird thing about this is that last night it was working. It kinda just magically stopped working.
The solution to this is not an obvious one, specially coming from older versions of laravel.
Thanks to this link.
Auth Session killed in Laravel 5.2
I was able to solve it, so I'll post the answer to help others who encounter the same issue.
Originally I just had this in my routes.
Route::post('app/login', 'Auth\AuthController#doLogin');
Route::group(['middleware' => ['web','auth']], function () {
Route::get('test',function(){
dd(Auth::user());// was always returning null
});
});
But, to get the login to persist, I had to do this
Route::group(['middleware' =>[ 'web']], function () {
Route::post('app/login', 'Auth\AuthController#doLogin');
});
Route::group(['middleware' => ['web','auth']], function () {
Route::get('test',function(){
echo Auth::user()->name;
});
});
Apparently any route thats going to call or register a session needs to employ the 'web' middleware.
Just add the "auth" middleware to your "test" route and try accessing it while logged in. It shouldn't give you any errors that way. If you try to access it without logging in, it should redirect you to whatever route is defined in the "auth" middleware.
By using "auth" middleware, you are basically ensuring that Auth::user() will always return a proper User instance.
Now, if this works then you can be sure that Laravel Auth is indeed persisting the user and the issue is somewhere else in your code.
I haven't noticed any issues with the Auth class in Laravel.
I have a contact form. On submit the POST request goes to a controller that handles the contact form (checks the request and emails the data). At the bottom of the controller I have this:
return back()->with('flash-message', 'Message!');
In the view I try to echo the message with
{{ session('flash-message') }}
This doesn't seem to work. The message is not in the session.
What could be wrong?
Im using:
Laravel version 5.2.7
please take Session variables with this way..
return redirect()->back()->with('flash-message','message');
and in View..
{{Session::get('flash-message')}}
I figured it out. It has to do with the Laravel 5.2 update. The middleware which is responsible for making that flash data available to all your views is not being utilized in normal Routes anymore. It was moved from the global middleware to the web middleware group. This post explains the issue and how to fix it.
Laravel 5.2 $errors not appearing in Blade
This post explains 2 ways to fix it:
In your kernel.php file, you can move the middleware \Illuminate\View\Middleware\ShareErrorsFromSession::class back to the protected $middleware property.
You can wrap all your web routes in the web middleware group (see below). Also place the Routes that handle the form here:
Route::group(['middleware' => 'web'], function() {
// Place all your web routes here...
});
You can do this.In the controller:
Session::flash('message','Empty input not accepted');
return back();
And in the view file to use this Session you can do same as above mentioned:
{{ \Session::get($message) }}
Hope this helps you....