I am using Laravel5 Auth system for my new project, I am able to use registration and login functions with out any problem but logout is not working as expected, however I get redirected to url specified at $redirectAfterLogout but it does not destroy session so even after hitting logout button I am able to see dashboard.
Does laravel has some bug in Auth system, please suggest, thanks
You have not provided any piece of code that you have used. However, the following code works:
public function getLogout(){
Auth::logout();
Session::flush();
return Redirect::to('/');
}
The Session::flush();clears all the existing sessions.
Using Laravel 5.2, I registered a listener, handled the logout event and called Session::flush as suggested above. Seemed to work pretty well. Hope this is helpful.
EventServiceProvider.php
protected $listen = [
'App\Events\SomeEvent' => [
'App\Listeners\EventListener',
],
'Illuminate\Auth\Events\Logout' => [
'App\Listeners\ClearSessionAfterUserLogout'
],
];
ClearSessionAfterUserLogout.php
public function handle(Logout $event)
{
Session::flush();
}
I had the same issue and I tried everything, but in the end I could fix it.
My problem was that when I hit on the logout button, before that I had some http requests that weren't answered yet, so even when the user was log out, later with the response of the pending requests it got logged in again. Here is an example:
Another Request | ***********************************
Logout Request | ********************
|
Time | --|------|-------------------|------|------>
t1 t2 t3 t4
So Removing those non-answered requests worked for me. I hope that this answer helps :)
By accepting the request object in a controller action (Remember to add this after the controller namespace declaration: use Auth; ):
/**
*
* Render page
*
* #route POST /user/{user_id}/logout
*
* #return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function logout(Request $request) {
Auth::logout();
$request->session()->flush();
}
I switched to the database session driver and used the following code in my logout action
$request->session()->getHandler()->destroy($request->session()->getId());
trait AuthenticatesUsers
public function logout(Request $request)
change this
$request->session()->regenerate();
to this
$request->session()->regenerate(true);
It seems that in the
/vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php
The function getLogout() is never reached, hence the logout() method never fires.
In my case, in my
/app/Http/routes.php
Iinstead of this:
Route::get('auth/logout', 'Auth\AuthController#getLogout');
I changed it to:
Route::get('auth/logout', 'Auth\AuthController#logout');
In your case you are not probably reaching the logout() method. If you are using Laravel 5 builting auth mechanism then you will run AuthenticatesAndRegistersUsers trait getLogout() method which does $this->auth->logout();
Find this code edit the method like below for debugging. If you see the string "Logging out" then you must be logged out. Ohterwise something is wrong with your routing and logout is just never executed.
/**
* Log the user out of the application.
*
* #return \Illuminate\Http\Response
*/
public function getLogout()
{
dd("Logging out");
$this->auth->logout();
return redirect('/');
}
I've been fighting with this, and I've come to a solution.
In short: The Laravel session reads and writes with middleware. It reads the stored session in at the start of the request, and writes any changes at the end of the request. If you make a redirect, then the current request never finishes, and the middleware write doesn't happen.
So, how to fix this? Depending on your implementation... you should return the redirect command rather than calling it directly.
return redirect($redirectAfterLogout)
I ran into a similar issue and it turned out using the 'file' driver for sessions somehow the server was creating files it could not modify later but there was no file permission warning. I switched to a redis implementation so I unfortunately can not say how to fix the file creation issue, but thought this might save someone some time.
You can simply override the logout method in AuthController.php
Here is code sample:
public function logout(){
Session::flush();
Auth::guard($this->getGuard())->logout();
return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/');
}
Auth()->logout();
For the newest versions.
Related
I am running Laravel 6 on Homestead. I have seen similar errors here but none specific to my situation.
If I log in, that's fine.
If I log out straight away, that fine too.
If I leave the screen to timeout beyond the session_lifetime set in .env, it wont log out without this error.
Argument 1 passed to Illuminate\Session\Middleware\StartSession::addCookieToResponse()
must be an instance of Symfony\Component\HttpFoundation\Response, string given,
called in /home/vagrant/code/MySite/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php on line 60
I'm learning Laravel and coming from vanilla php, I haven't a clue where to start looking. Thanks in advance.
I dont have access to login routes am using Auth:routes() in web.php. I think i may have solved the problem by overriding logout(). Seems a bit to simplistic. Wonder if this is secure?
public function logout(Request $request){
Auth::logout();
return redirect()->route('home');
}
Edit, sorry that does not solve my problem. It works within active session time but outside that i have same problem
Unfortunately, that does not work for me. I see the logic why it should but same error shows. As an experiment, I just returned "hello world" on its own in logout method and sure enough it just shows up on logout page no errors. But if I do this I get the same error as above (no logout functions just a rtn view)
public function logout(Request $request){
//if (Auth::check()) {
// Auth::logout();
//}
//return redirect()->route('home');
//$request->session()->flush();
return view('front.pages.aboutus');
//return "hello world";
}
As you can see I have been experimenting with flush() too but no joy.
Laravel uses session cookies. If you give that cookie a lifetime, the browser will delete that cookie as soon as the lifetime is expired. Therefore on your Laravel project you can no longer log out the user by removing the cookie manually since the cookie is already gone.
EDIT to make my answer correspond to the changed details in the question:
Two possible solutions: If you can change the routes, make your logout route only available to logged in users. If they're already logged out, just redirect to the homepage. (See Route middlewares in Laravel Authentication Docs)
As a more direct approach if you can't/don't want to manipulate your routes, you can just perform an Auth::check() in your logout function.
If Auth::check() returns true, the user is logged in and you need to log them out first:
public function logout(Request $request){
if (Auth::check()) {
Auth::logout();
}
return redirect()->route('home');
}
(see Laravel Docs for Retrieving The Authenticated User
Ok eventually found the problem. I had a string returned in app/exceptions handler method when i was trying to debug a 419 problem and forgot to change it back
public function render($request, Exception $exception)
{
if ($exception instanceof \Illuminate\Session\TokenMismatchException) {
return redirect()->route('login'); // <- the solution
//return "hello world";// <- the problem
}
return parent::render($request, $exception);
}
I think it is a good solution to have the user go somewhere useful after clicking logout regardless of whether the actual session has timed out or not. A 419? pretty useless. At least the above solution sends them somewhere. It could probably be a different route choice from mine here also I would imagine. Thanks Mastacheata for your help along the way.
I am using Laravel 5.4. I ran the make:auth command to scaffold out my auth controllers and views. I can register a new account without issue as it is showing up in my database. However when I try to login, the login page simply refreshes without any errors being thrown. In the login controller I have the redirect set to '/home' but this isn't happening. Any idea what could be causing this? I have a feeling this is because I made the required tweaks to allow users to login with a username rather than email. But I'm not sure what is causing my login not to work when everything else works fine.
Below is my login controller.
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'logout']);
}
public function username()
{
return 'username';
}
}
Do a quick check to see if the route is being handled.
You might have to add Auth::routes(); in your web.php
Resource:
laravel 5.3 new Auth::routes()
Once you've run php artisan make:auth you need to also run the migrations with php artisan migrate have you done this?
I had this problem using Laravel 8.0 and found no helpful response over the internet... until I taught of checking the APP_URL set in my env...
Because I have other apps set up on other ports on the same localhost, I simply changed APP_URL from http://localhost to http://localhost:8003/, i.e, specifying the port this App is on.
Other steps I took that may contributes include generating new APP_KEY and refreshing my migration.
It's been many years, but, this took my 3 days to figure... I hope it helps someone.
I have a feeling this is a very dumb question and there's probably something really tiny I just overlooked, but I'm stumped anyway.
Currently, I have an app with a few pages that are protected through middleware. If the user does not meet the requirements of these middleware, they are redirected to a login page. Now after they log in, I want them to be sent back to the page they tried to visit.
I've tried numerous things to accomplish this, but none work. What I'm trying to do now is the following:
User attempts to access an admin page (for example /admin): PagesController#adminDashboard
When they access the overview() method in the controller (same as index(), but for admins), a session variable is set containing the url they tried to visit (/admin)
The user is redirected to the login page and logs in (SessionsController#create and #store)
After logging in, they are redirected to the session variable with the intended URL
This is how I tried to do it:
PagesController
public function adminDashboard()
{
$intended = '/admin';
session('intended-url', $intended);
//dd(session('intended-url');
$schools = School::all();
$articles = Article::all();
$sights = Sight::all();
return view('admin', compact('sights', 'articles', 'schools'));
}
SessionsController
public function store()
{
/*
...
*/
$intendedURL = session('intended-url');
if($intendedURL != null)
{
return redirect($intendedURL);
}
else
{
return redirect()->home();
}
Using dd() a few times here and there, I found out that it doesn't even set the session variable at the very start (commented dd() in PagesController returns null).
I've tried doing this using Session::put(), Session::set(), using square brackets as in session(['intended-url', '/admin']), but none of it gives me the result I'm looking for :(
Does anyone have any advice on how to do this, or perhaps a different way of accomplishing the same goal, but more efficiently? Thank you!
EDIT: I don't think the default Laravel redirect to intended page will work here, since I rewrote most of the login system from scratch to suit some specific needs. Unless anyone knows how that redirect works behind the scenes and I can over-/rewrite it
If you are using the default auth system, you can use this to redirect users to the page they wanted to view:
return redirect()->intended('fallback/uri');
why u are not using middleware just make new middleware
php artisan make:middleware admin
and add this code of public function handle
if (!Auth::guest() && Auth::user()->admin) {
return $next($request);
}
return redirect('/')->with('warning', 'This Area only For Admin');
add this code in kernal on protected $routeMiddleware
protected $routeMiddleware = [
'admin' => \App\Http\Middleware\admin::class,
];
make new column in users table
$table->boolean('admin')->default(false);
now you can use your construct function
public function __construct()
{
$this->middleware('admin');
}
Note:- where u add $this->middleware('admin'); all controller will be locked for users and guest only admin can use this controller
(I'm a beginner of Laravel)
I'm using Laravel 5.2. I have successfully enabled the Authentication; by doing the php artisan make:auth and stuffs.
So my login is working.
Now i need to do something once someone has logged in. For an simple example:
LOGIN:
Once a user has logged in, write a value into Session.
For example: $request->session()->put('UserAgent', $ClientUserAgent);
LOGOUT:
Same thing to do, once a user has logged out, delete the custom Session value.
For example: $request->session()->forget('UserAgent');
I'm not sure whether there are (things like) hooks or Event Listeners, Event Handlers, or something like that.
How can i do it please?
For newer versions of Laravel
If you are only doing something very simple then creating an event handler seems overkill to me. Laravel has an empty method included in the AuthenticatesUsers class for this purpose.
Just place the following method inside app\Http\Controllers\LoginController (overriding it):
protected function authenticated(Request $request, $user)
{
// stuff to do after user logs in
}
For the post login, you can do that by modifying App/Http/Controllers/Auth/AuthController.php
Add authenticated() into that class to override the default one:
use Illuminate\Http\Request;
protected function authenticated(Request $request, User $user) {
// put your thing in here
return redirect()->intended($this->redirectPath());
}
For the logout, add this function into the same class:
use Auth;
protected function getLogout()
{
Auth::logout();
// do something here
return redirect('/');
}
You could try setting up event listeners for the Auth events that are fired.
You can setup a listener that listens for Illuminate\Auth\Events\Login to handle what you need post login and Illuminate\Auth\Events\Logout for post logout.
Laravel Docs - Authentication - Events
Alief's Answer below works fine as expected. But as i googled through, using the Event Handlers is probably the more preferred way. (It works like custom hooks).
So without any less respects to Alief's Answer below, let me choose --> this Event Handers approach i just found out.
Thanks all with regards!
If you are testing, with authenticated(Request $request, User $user) method dont use alert inside this method to test, it will not show any result, so better put some insert query or something like that to test this method.
Why not simple check for
if(Auth::check()){
//your code
}
Make sure you include use Auth;
When I use the built-in Authentication and try to log the user out at /auth/logout - it does not work as hoped. It appears to keep the user logged in. But when I clear my browser cache, I can see that is has actually logged the user out.
I don't get any errors on the page nor errors in the log file.
I am guessing that Session::flush() at the logout method would possibly solve this - but I don't know where to put it.. Can someone point me in the right direction?
For anyone that has problems solving it with the accepted solution: I started with Laravel 5.1 and updated to 5.2. The following fix worked for me:
Try changing your 'logout' route to
Route::get('auth/logout', 'Auth\AuthController#logout');
or in AuthController constructor add
public function __construct()
{
$this->middleware('guest', ['except' => ['logout', 'getLogout']]);
}
Taken from: https://stackoverflow.com/a/34667356/1275778 (also check the other answers there if you're still having problems afterwards)
Try this..
Put In following code "class AuthController extends Controller"
public function getLogout()
{
$this->auth->logout();
Session::flush();
return redirect('/');
}
I had the same problem.
The problem was actually a simple little error in the configuration of the route and controller.
You see the route actually specifies a method of getLogout and the controller exception is looking for logout.
The only thing you need to do is change the exception in the controller. No need for any additional methods. The getLogout method already exists and works perfectly.
Here is the actual code
app/Http/routes.php
Route::get('auth/logout', 'Auth\AuthController#getLogout');
app/Http/Controllers/Auth/AuthController.php
public function __construct()
{
$this->middleware($this->guestMiddleware(), ['except' => 'logout']);
}
The _construct method should look like that:
public function __construct()
{
$this->middleware($this->guestMiddleware(), ['except' => 'getLogout']);
}
this ocurrs because the middleware is called for every route. you can add a exception to " logout route" in App\Http\Middleware\RedirectIfAuthenticated.php
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (!$request->is('/logout') && Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
}
For logout in laravel 5.6 and later version :
use in your view page:
Logout
use this in your web.php
Route::get('logout', 'Auth\LoginController#logout');
I had the same problem with updated laravel 5.2. I have used laravel's auth controller and I solved this problem using like,
/logout instead of /auth/logout same for /register and /login in instead of using /auth/register and /auth/login.
Laravel 5.2 the url is a little different ...
Use this
php artisan make:auth
This will generate the routes for auth and some templates for login e register...
Be careful to use this with existing projects, it can make changes to your code
Not enough on browsers that recover your tabs after crash (Chrome doesn't delete session cookies) . Also, after redirect a new session is created. Solution: in AuthController, as mentioned above, in getLogout, set a variable and pass it to redirect:
$data['logout'] = true;
return redirect('/')->with('data',$data);
In your home view do this:
#if(session()->has('data') && session('data')['logout'])
{{session_unset()}}
{{setcookie('laravel_session', "", -1, "/")}}
#endif
I believe Laravel redirect reinitialises Session. So after redirect, in view, reset delete cookie. Anybody can comment on this? Is this the right reason this works?
To log out a user with Laravel using the built in authentication tools, it is as simple as using Auth::logout();.
Please also check the various session settings in config/session.php if the sessions behaves unpredictably.
Solution is very very simple
in Http->Middleware->Authenticate.php change "login" in else statement to "/"
return redirect()->guest('/');
and define following route in routes.php
Route::get('/', function () {
return view('login');
});
for logout call following function:
public function getlogout(){
\Auth::logout();
return redirect('/home');
}
this is important redirect to "/home" instead of "/" that first calls $this->middleware('auth');
and then in middleware redirect to "/"
I had the same problem after upgrading to Laravel 5.3. To fix it, I noticed that the traits used in
App\Http\Controllers\Auth\AuthController
are outdated, so I changed the line
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
into
use AuthenticatesUsers;
and also the line in the constructor
$this->middleware($this->guestMiddleware(), ['except' => 'logout']);
into
$this->middleware('guest', ['except' => ['logout', 'getLogout']]);
Then the method App\Http\Controllers\Auth\AuthController#logout started to work properly.
In 5.4 this worked for me...
Logout
<form id="logout-form" action="/logout" method="POST" style="display: none;">{{ csrf_field() }}</form>
in case no any solutions is working try this
for multiple custom guards if you use auth()->logout then it wont work
just use auth('your-guard-name')->logout(); then it will work fine.
It is a quite old thread but finally I found a simple trick to log the user out from the server:
return Auth::logout();