making a log in as user in laravel - php

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.

Related

Remove another user's session

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);
}
}

Laravel REST structuring

I am making a website which will have user login. Login form now leads to admin panel if your role is admin (route is behind admin middleware), and it leads back to home page if your role is user. Back on the home page you have the ability to see your profile page and add a product (which is behind auth middleware).
My question is what is the best approach to form my routes?
If I make site.com/user/{id} route, user ID's will be exposed to each user which logs in, as well as for example editing a product with site.com/user/{id}/product/{product_id}.
I see some security issues here and am wondering if a better solution is making site.com/profile route which will in turn in controller take Auth::user() not exposing ID's in the process?
Add your route without the ID and use Auth::user() It's best practice and makes your routes simpler
Public function profile(){
$user = Auth::user();
return view('profile', compact('user');
}
The above code is more straight forward than this:
Public function profile($id){
$user = User::find($id);
//prevent authenticated from viewing other users
if($user == Auth::user()){
return view('profile', compact('user');
}else{
//return something else
}
}
If you are worried about exposing user ID you can try use something like hashids, where ID will be encoded.
Here you go:
encode the id and product_id with base64_encode()
Example pass the id and product_id in url by encoding with base64_encode()
and when you want to use it use like this:
Route::get('user/{id}/product/{product_id}', function($code){
$id = base64_decode($id);
$product_id = base64_decode($product_id);
});

How can restrict a user to access some section of my application in laravel 5.4

I have different type of users in my application. Ex: Super Admin, Client, Staff and HR.
Now I want to give all access to Super Admin and some for Client and some for Staff and some for HR also.
Lets say I have 3 section
a) Manage Staff
b) Manage Clients
c) Manage Projects
d) Manage Designation
Now I want to give access super admin a,b,c & d And for Client only C And For Staff Only c & d And for HR only a.
I have done it by checking the User type form my user table. (Not Right Way)
Lets Say I have a URL localhost/myApp/staff [ this can be access by Super Admin]
But when I logged in as Client and I hit the above URL then He/She is able to get the list of staffs, Which I want to restrict and redirect back him with some message.
How can I achive this in Laravel 5.4. Thanks in advance.
You need to use middleware for that.
See in the doc:
https://laravel.com/docs/5.4/middleware
A little example
public function handle($request, Closure $next)
{
$user = $request->user();
if ($user && $user->isAdmin())
{
return $next($request);
}
return new RedirectResponse(url('/home'));
}
}
With a middleware like that , if the user is Admin he can go on the page if not it will be redirect on the homepage.
The isAdmin is a function , you gonna need to create in your user Model like that.
public function isAdmin()
{
return $this->groups->name =='Admin';
}
In the function for the staff url check the type of user:
function staff(){
if(Auth::user ! = 'super-admin')
return redirect('/')
}
else{
//show the staff
}
You need check this page out Authenticate A User Instance.
Authenticate A User Instance
If you need to log an existing user instance into your application, you may call the login method with the user instance. The given object must be an implementation of the Illuminate\Contracts\Auth\Authenticatable contract.
Auth::login($user);
// Login and "remember" the given user...
Auth::login($user, true);`
Of course, you may specify the guard instance you would like to use:
Auth::guard('admin')->login($user);
You can follow the Laravel documentation or add a new field called 'role' or what ever to authenticate.

Functionality for admin to log in in as user in Laravel 5.3

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.

Laravel 5 Logout Specific User

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

Categories