There is possible to get another users session? Suppose, there is user with admin privilegies and I need that admin have functionality, to access another user's session and remove it. (So that another user will automatically logged out).
Is there some tools in laravel for this? or I need do same things, as I would do for native PHP application ?
Have an admin panel and have the setting to block the user.
Have a column in your database table, say is_blocked with datatype as tinyint, with 1 meaning the user is blocked.
In your application, have an additional check of whether the current logged in user is blocked in a custom made middleware. If yes, log them out, else continue with request target.
Middleware Snippet:
<?php
namespace App\Http\Middleware;
use Closure;
use Auth;
use Session;
class IsBlockedMiddleware{
public function handle($request, Closure $next){
Auth::user()->refresh();
if(Auth::user()->blocked === 1){
Auth::logout();
Session::flash('error','Your account is blocked'); // show the flash message in your blade file
return redirect()->route('login');
}
return $next($request);
}
}
Related
i want to know if there is any way to simulate the login as user and make the session for that user .i want my help-desk to see the site from users vision so they need to log in as user as long as i cant show the user s password to the admin (its not possible as far as i know if its not that would be a good solution too ). i want to place a button with some text for example :
LoginAsThisUser
and when my help desk clicks on the button he logs in as the user is there any way to do that ??
It's possible, and it's fairly simple to do. All you need to do is to create a route, something like this:
Route::get('admin/login-as-user/{id}', 'Admin\UserController#loginAsUser')->name('login.as.user');
After that, pass the route to your LoginAsThisUser button with desired user id :
LoginAsThisUser
And create a function in your controller:
public function loginAsUser($id)
{
$user = User::findOrFail($id);
Auth::login($user);
return redirect('/');
}
Note: this is not tested, let me know if you encounter any errors.
use Illuminate\Support\Facades\Auth;
//use user_id
Auth::loginUsingId(1);
// Login and "remember" the given user...
Auth::loginUsingId(1, true);
$user=User::find($userId);
//use Authenticatable user
Auth::login($user);
// Login and "remember" the given user...
Auth::login($user, true);
also use
Auth::guard('notDeafault')->login($user);
if you want switch default guard
With the Auth facade, you can use the loginUsingId method
Auth::loginUsingId($user_id);
This method allows you to force login without a password. But it does not allow you to retrieve cookies or cache from your user's browser that may impact their viewing.
I am begginer in Laravel. I am use Laravel 5.8 in my project.
I need to do something so that a specific route can be viewed by a user with a php adult = 1 session.
I have route:
Route::get('/', 'FrontendController#index')->name('index');
Route::get('/sample1', 'FrontendController#sample1')->name('sample1');
The SAMPLE1 view is for users with php adult = 1 session.
If the user does not have such a session - it must be automatically redirected to # index
How can you do this?
You can achieve this by creating a custom middleware, take a look at the documentation here:
https://laravel.com/docs/5.8/middleware
Instead of using session, you can maintain a user is adult or not on the users table, which means you can access this info via authenticated user (which is available throughout the whole app).
For e.g. in your app, use php artisan make:auth and this will scaffold out everything you need to for a register/login system. Before you run the migration, add a new field to the create_users_table migration, e.g. $table->boolean('adult')->default(false);
Then once the migration is ran, you can create a new middleware using: php artisan make:middleware CheckAdult with something like this:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckAdult
{
public function handle($request, Closure $next)
{
if (!auth()->check() || !auth()->user()->adult) {
return redirect('/');
}
return $next($request);
}
}
The above middleware will redirect anyone who is not logged in or have adult = 0 back to index page, otherwise continue with their request.
Then register the middleware and use it in the routes; as per the documentation.
you can use auth and middleware to achieve this. the simple logic would be something like this: $id = Auth::user()->adult; in your controller to check for users. ofcorse adult is a field in your table.
//on top of your controller place this
public function __construct()
{
$this->middleware('auth');
}
//control logic to check user
if($adult==1){
//perform unique task
}else{
return redirect('/')->with('message','You are not permitted')
}
Is it possible to create some user which will automatically included if user is not authenticated? For example, if I call $request->user() in controller I will get NULL. I want to get some default user model in this case (maybe instance of App\User with id == 0). I need it because I want to attach some roles and permissions to guest users via entrust module.
You could add a simple middleware that would authenticate users as Guest user if they aren't authenticated. The code below should do the trick:
class LoginAsGuest {
public function handle($request, Closure $next)
{
if (!Auth::id()) {
Auth::loginUsingId($guestUserId);
}
}
}
Make sure this middleware runs last so that user has a chance to be authenticated using their session/cookie data.
Building an app in Laravel 5.3, one of the functionalities is for the admin to be able to log into the app as a user, to be able to see what that specific user can see, while maintaining his admin session to be able to go back to the user list and be possible to log in as another user without having to re-authenticate.
Currently implemented the basic out-of-the-box Laravel Auth, meaning if I start another auth session it will terminate my admin session making me having to re-login.
I have checked Laravel Multi Auth but seems to work with two tables (user,admin), which in my case we use one user table and use an ACL for managing roles and deciding whos admin and whos user.
What programming logic ideas do you guys have for this solution? Trying to find other opinions/ideas in how this could be implemented in Laravel 5.x
I've implemented the feature on a project recently. I did this using the session and a middleware. This is how I did it:
Create a controller 'ImpersonateController' and Set two routes for impersonateIn and impersonateOut for the purpose.
Route::get('impersonateIn/{user}', 'ImpersonateController#impersonateIn');
Route::get('impersonateOut', 'ImpersonateController#impersonateOut');
In the ImpersonateController#impersonateIn method just set the user id you want to log in and the URL backUrl into the session variable.
public function impersonateIn($id)
{
session(['impersonated' => $id, 'backUrl' => \URL::previous()]);
return redirect()->to('dashboard');
}
public function impersonateOut()
{
$back_url = Request::session()->get('backUrl');
Request::session()->forget('impersonated', 'secretUrl');
return $back_url ?
redirect()->to($back_url) :
redirect()->to('dashboard');
}
The first part is done. Now every request need to check the if the session has the
impersonated variable set. A good place to do that is a middleware.
Create a middleware to check the session on the handle method. If the impersonated found then log as the user using the Auth::onceUsingId() for the current request only.
class ImpersonateMiddleware
{
public function handle($request, Closure $next)
{
if(Request::session()->has('impersonated'))
{
Auth::onceUsingId(Request::session()->get('impersonated'));
}
}
}
Now you just need to apply the middleware for every request. The best place to do this from the Http/Kernel.php
protected $middlewareGroups = [
'web' => [
//....
\App\Http\Middleware\ImpersonateMiddleware::class,
],
];
The only remaining thing is you need to check the session and replace the logout route to the impersonateOut. Now when the admin logged out from the user will be redirected to the old route.
That's it!
Are you sure you really have to login?
I would stay logged in as admin and simulate user login.
You can allow admin access to all the databases.
In your controller you can use User::find($user_id) instead of Auth::user() for accessing user's data.
https://laravel.com/docs/5.3/database
https://laravel.com/docs/5.3/eloquent
Personaly, I would do this with sessions. I have not used Laravel but I use PHP often, so my answer will be in PHP.
In the header page, you most likely have some kind of session check to see if the user is logged in. For example:
<? php
session_start();
if (isset($_SESSION['user'])){
//do stuff with the user session
} else {
die('User not logged in!');
}
?>
I would change this to something like:
<? php
session_start();
if (isset($_SESSION['fakeuser'])){
//do stuff with the user session
//change logout button to destroy this session instead of logging the user out
}
elseif (isset($_SESSION['user'])){
//do stuff with the user session
} else {
die('User not logged in!');
}
?>
In the page in which you swap users, you would just simply copy the way a session starts when a user logs in. To switch users, you destroy the new 'fakeuser' and you are back to your old session + admin permissions without having to log back in again.
That's the logical approach I would take anyways.
In my laravel 5 application there is a function to allow users with the admin role to reset passwords of anyone not an admin, however this does not force the person to logout and login again. How can I force the user to log out once their password has been changed? I have not made any changes to the middleware for authenticating users or anything.
I don't know if it will work but you can try:
// get current user
$user = Auth::user();
// logout user
$userToLogout = User::find(5);
Auth::setUser($userToLogout);
Auth::logout();
// set again current user
Auth::setUser($user);
I think that the fastest solution is to add a flag to the users DB table, for example a boolean column to_logout and the in the Auth middleware add something like this code.
$user = Auth::user();
if($user->to_logout){
Auth::logout();
$user->update(['to_update' => 0]);
return redirect('/');
}
Trying to avoid additional complexity like adding fields to db, after little bit of investigation I came across next solution.
Idea is based around Laravel 5.4, but should be compatible with all 5.x releases.
The problem lies in way Laravel handles logout. As we can see in https://github.com/laravel/framework/blob/5.4/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php#L154
public function logout(Request $request)
{
$this->guard()->logout();
$request->session()->invalidate();
return redirect('/');
}
The line $request->session()->invalidate(); is flushing request session data and regenerate the ID. So after this one, if we had multiple guards enabled, they all will be logged out.
The idea is to remove just one, session key which corresponds to the current user we are logging out. If we inspect our session (pay attention to "login_*" keys), while users from different guards are logged in, we'll get something like this:
array:5 [▼
"_token" => "qB4zDqDbknpO7FOrfNQ3YuFxpnji95uamJflxSkV"
"_previous" => array:1 [▶]
"_flash" => array:2 [▶]
"login_admin_51ba36addc2b2f9401580f014c7f58ea4e30989d" => 74
"login_user_51ba36addc2b2f9401580f014c7f58ea4e30989d" => 23
]
Instead of flushing whole session, we just need to delete this single, corresponding key. To get current guard session name (session key in example above), we can use guard method:
https://github.com/laravel/framework/blob/5.4/src/Illuminate/Auth/SessionGuard.php#L622
Now we have everything we need to perform this task. Here is the example from the project I'm currently on:
namespace App\Http\Controllers\Admin\Auth;
use Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
public function __construct()
{
$this->middleware('guest:admin', ['except' => 'logout']);
}
protected function guard()
{
return Auth::guard('admin');
}
public function logout()
{
// Get the session key for this user
$sessionKey = $this->guard()->getName();
// Logout current user by guard
$this->guard()->logout();
// Delete single session key (just for this user)
$request->session()->forget($sessionKey);
// After logout, redirect to login screen again
return redirect()->route('admin.login');
}
// ... Other code ...
}
With LoginController::logout method we're overriding trait logout (default Laravel logout logic) with our custom, almost the same, but which will allow us to logout single user.
The same logic applies for all our login controllers depending on how much different guards we have.
I just finished this solution and after quick testing it seems to be working fine, but please inspect it carefully before implementing.
If you use Laravel 5.2, you can change session storage engine to Database. In this case every session record will also contain user's ID.
All you need is just to remove respective row from database.
Looking over the docs, it does not appear there is any built-in function for this and a similar request has been proposed which also describes the problem of tracking a single user who has multiple sessions open on more than one device.
I believe you will need to create a custom solution, for example (as #Dinar mentioned) if you are storing user sessions in a database then you could retrieve and destroy a specific user's session when a certain condition is met - changing their password.
$findUser = User::find($userId);
\Session::getHandler()->destroy($findUser->session_id);
Laravel 5.5