I am testing a Laravel 5.1 page that requires the user to be logged in. My project uses the Cartalyst/Sentinel packing for authentication.
I tried this but I doesn't recognize that the user is logged in.
public function testPageWithLogin()
{
$user = Sentinel::findById(2);
$this->actingAs($user)
->withSession([])
->visit('/page')
->dontSee('Whoops')
->dontSee('login');
}
What can I do so that the user will be seen as logged in?
I forgot to log the user in using the Sentinel::login method. The user was legit just not seen as logged in.
This is the way it should have been done.
public function testPageWithLogin()
{
$user = Sentinel::findById(2);
Sentinel::login($user);
$this->actingAs($user)
->withSession([])
->visit('/page')
->dontSee('Whoops')
->dontSee('login');
}
Related
I am trying to create a "Shadow" user feature, it's basically just to allow admins to log in as another user to use the system as the "shadowed user" would.
I've used Auth::loginUsingId before but i can't figure out why the below isn't working.
public function shadowUser($id, Request $request){
$user = User::query()->find($id);
$previousUserId = $request->user()->id;
Session()->flush();
Session()->put('shadow.user.id', $previousUserId);
$shadowedUser = Auth::loginUsingId($user->id);
dump(Auth::check());
return redirect()->route('home');
}
If I dump out the $shadowedUser it shows the correct user and the Auth::check() returns true.
I have also tried these but they made no difference: Auth::loginUsingId(1, true);, Auth::guard($guard)->loginUsingId($user->ID); and Auth::login($user, true);
There's no crazy middleware just laravel's defaults.
I've tried a few things like removing the session flush but it always just logs me out.
I found that Laravel sessions are a bit funky in this scenario, it looks like you're trying to log someone in when the session is already active, log the current user out, flush the session then log in the new user, this way it will tell Laravel that this is a new user signing in and reset the session.
In your script, once you've logged the user out, flushed the session and logged the new user in, add the previous users id to the new session otherwise it will get deleted then you'll be able to see the previous user who was logged in, or the person shadowing you in this case.
public function shadowUser($id, Request $request){
$user = User::query()->find($id);
$previousUserId = $request->user()->id;
Auth::logout($guard);
Session()->flush();
Auth::loginUsingId($user->id);
Session()->put('shadow.user.id', $previousUserId);
dump(Auth::check());
return redirect()->route('home');
}
I have created a few forms in laravel. I want to restrict access to one of them only to a specific user.
I want to create a user and password myself.
This is my routes excerpt. This is the route I want to protect from access
Route::get('/tabledata_id_title', 'KedivimController#appearanceiddata');
This is my controller excerpt:
public function appearanceiddata()
{
//$magic = DB::table('prog_title')->select('pr_id', 'pr_title')->get();
$magic = DB::table('prog_title')->select('pr_id', 'pr_title')-> where('pr_index', '=', 1)->get();
return view ('takealook', ['magical' => $magic]);
}
This is a short fix for your problem.
public function appearanceiddata()
{
if (!Auth::guard('web')->check()) //check if someone is logged in
{
//redirect to login page.
}
else {
/*Check if the logged in user is your desired user.
Maybe try matching the logged in id with your desired id.
If you find that a user is logged in but they are not your desired user
then you may redirect them in some other place or show them a message. */
}
//$magic = DB::table('prog_title')->select('pr_id', 'pr_title')->get();
$magic = DB::table('prog_title')->select('pr_id', 'pr_title')-> where('pr_index', '=', 1)->get();
return view ('takealook', ['magical' => $magic]);
}
However, this practice is ok if you have one or two restricted field. But if you have more than that then you should read about middleware.
I have overwritten Login and Logout functionality as I need to check many more conditions to authenticate the user like below.
public function login(Request $request)
{
$this->validateLogin($request);
$input=$request->all();
$user=User::where('username',$input['username'])->first();
//If Temp Password is set
if(strlen($user->temp_password)>10)
{
if (Hash::check($input['password'], $user->temp_password))
{
Auth::login($user);
$this->setUserSession($user);
$landing_page=Menu::find($user->landing_page);
return redirect()->route($landing_page->href);
}
else {
session()->put('failure','Invalid Username or Password');
return redirect('/login');
}
}
else{ //If Temp password is not set
if (Hash::check($input['password'], $user->password))
{
Auth::login($user);
$this->setUserSession($user);
$landing_page=Menu::find($user->landing_page);
return redirect()->route($landing_page->href);
}
else {
session()->put('failure','Invalid Username or Password');
return redirect('/login');
}
}
}
Now I need to restrict Same user from login once again in some other screen or place. I have checked Session Data but nothing is stored as Unique for a User.
ie. If a username admin is loged in US the same username admin must not be allowed to login from UK.
Update
Oh bagga, question wasn't quite clear. You are trying to restrict the number of sessions to 1 only. If I get it, then you will have to use a database session driver. Right now, I think you may be using the default driver (file). It only checks the session within the same browser. Using database session may allow you to check for session everywhere, and restrict the number of connections.
First, make sure your routes are within the web middleware so they can access sessions. Then, inside of the web middleware, create a group of routes that are only accessible for users who are not logged in.
Route::group(['middleware' => 'guest'], function () {
Route::get('login', 'LoginController#login');
// any other route
});
Logged in users won't be able to access the login route anymore.
You could also do the check in your login function to see if the user's is already connected by using
if (Auth::check()) {
// user is connected
// redirect them
}
What does this->setUserSession($user) do?
You can do this using login token.
Generate a login token and keep it in database.
And check for it's entry in database while logging in.
If it doesn't exist let log in success.
Else fail.
And delete login token every time user logs out.
Or
you can generate new token on each login success. And deleting old token and invalidating the old login.
But in this case you have to keep that token in session and for each request you have to check that token with database token.
If it matches, allow user
Else logout the user with notice.
I'll prefer the second method personally.
As you can check for the token in the middleware itself.
I'm trying to build a function where a user can delete their own account while they are logged in. I'm struggling to find any example or logic/best practices.
The controller looks like this:
public function postDestroy() {
$user = User::find(Auth::user()->id);
$user = DB::delete('delete from users')->user(id);
return Redirect::route('site-home')->with('global', 'Your account has been deleted!');
}
I'm trying to grab the current Auth (logged in) user and use their id to delete them from the database. Then send them to the home page with a message.
Also, do I need to make sure the session is properly closed during this process, such as Auth::logout(); ?
I'm pretty new to Laravel, so any help would be appreciated.
Not sure how your routing looks like, but this should do the job.
$user = \User::find(Auth::user()->id);
Auth::logout();
if ($user->delete()) {
return Redirect::route('site-home')->with('global', 'Your account has been deleted!');
}
You should logout user before delete.
You merely gotta do like this:
$user=auth()->user();
$user->delete();
I'm just working on the user management-component of our new project.
The plan is:
User registers on the page with minimal amount of account data (username, pass, email)
User gets an email with an activation link to activate the account
User clicks on the link and activates his account
The system logs in the user after automatically after activation and redirects him to kind of a dashboard with account information (last login, hi "username", etc.)
But there are some problems with the auto login. this is the part of the code i use:
<?php
...
// set userstatus to "active" and delete meta information "activation_key"
// then automatically login
$this->User->id = $id;
$this->User->saveField('modified', date('Y-m-d H:i:s') );
$this->User->saveField('status', 1 );
// $this->User->deleteActivationKey ....
$this->Auth->login($this->User->read());
$this->Session->setFlash(__('Successfully activated account. You are now logged in.'));
$this->User->saveField('last_login', date('Y-m-d H:i:s') );
$this->redirect(array('controller' => 'pages'));
...
This works so far, until you want to get information about the logged in user with the user() function of the Auth Component.
We're using this in AppController->beforeRender, to have user information application wide:
$this->set('auth', $this->Auth->user());
but after that auto login action, i'm getting undefined index notices. (e.g. by accessing $auth['id'] in a view). print_r() shows me only the username and hashed password of the current user.
If you login manually, everything works fine. it must be something with the automatic login after the account activation.
Seems to be a problem with the session? What am i doing wrong?
Found a solution after testing many variations.
Works now with:
$user = $this->User->findById($id);
$user = $user['User'];
$this->Auth->login($user);
Don't know why, i thought i tried this way already and that did not work.
Have you tried this? (CakePHP 2.x)
public function signup() {
if (!empty($this->request->data)) {
// Registration stuff
// Auto login
if ($this->Auth->login()) {
$this->redirect('/');
}
}
}
That simple!