Laravel 5 with entrust - hasRole not working - authentication

I have a logged in user and the code here works:
#if( Auth::check() )
Logged in as: {{ Auth::user()->firstname }} {{ Auth::user()->lastname }}
#endif
I'm using zizaco/entrust and it's all working. I've created roles and permissions and given my user the admin role which has administrative permission.
So why doesn't this work:
$user = Auth::user();
print_r($user->hasRole('admin'));
If I print_r the $user I can see that the Auth user is loaded, but hasRole is not working. I was just testing this within the blade template at the moment but tried it in the Controller with the same result. My error is:
BadMethodCallException in Builder.php line 1992:
Call to undefined method Illuminate\Database\Query\Builder::hasRole()
My user model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Zizaco\Entrust\Traits\EntrustUserTrait;
class User extends Model {
use EntrustUserTrait;
protected $table = 'users';
public $timestamps = true;
use SoftDeletes;
protected $dates = ['deleted_at'];
}
UPDATE
I realized hasRole works for me when I look up the user this way (returns App\Models\User Object):
$user = \App\Models\User::find( \Auth::user()->id );
but NOT when I find the user this way (returns App\User Object ):
$user = \Auth::user();
I rather would have thought it would work the other way, when I pull up the App\User I'd have access to hasRole but not necessarily when I search for a user. I thought hasRole would work right from the Auth::user() without having to lookup the user with the user model...???

Found the issue..
in config/auth.php I had
'model' => 'App\User',
My namespace requires
'model' => 'App\Models\User',

Thanks for you update, it was a problem for me as well. And I used your advice and I put in my HomeController
public function index()
{
$user = User::find( \Auth::user()->id );
return view('home', compact('user'));
}
and then in my Home View
#if ($user->hasRole('Admin'))
<li>Create User</li>
#endif
<li>User List</li>
<li>Create Client</li>
<li>Create Payment</li>
and everything works perfect...

Related

Redirect user after login in laravel 5.1

I am trying to implement a feature where, after logging in, a user gets redirected to a URL depending on their role. I have the roles part set up, but I'm having trouble testing the user's properties immediately after login.
I followed the instructions here to create a user login page. I have an AuthController that looks like this:
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class AuthController extends Controller {
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
protected $redirectTo = '/test';
...
}
My __construct() function validates the user, but I don't know how to access the user object only immediately after login. This is what I presently have:
public function __construct() {
$this->middleware('guest', ['except' => 'getLogout']);
if ( \Auth::check() ) {
$user = \Auth::user();
if ( $user->admin() ) {
// an admin
$this->redirectTo = '/admin';
} else {
// it's a client
$this->redirectTo = '/client/dashboard';
}
}
$user = \Auth::user();
if ( is_object($user) ) {
} else {
$this->redirectTo = '/auth-not-object';
}
}
When I first attempt to log in with an administrator account, I get to the path /auth-not-object, because there isn't any authenticated user object at that point.
After having attempted to log in, but getting a bad redirect, when I revisit the /login url, I get redirected to /home, which I believe is the default $redirectTo in the traits this class uses. So that means we've passed the AuthController __construct() method without having changed the $redirectTo, even though there is an authenticated user.
I've found other questions, such as How to add extra logic on login condition in Laravel 5.2 and laravel redirect to url after login, but I don't understand how to apply those answers. For instance, the accepted answer to the second question shows new methods, getCredentials() and login(), which don't exist in the poster's original class. I am not sure in what class to add them, or where to call them from, in my codebase.
Other similar answers show a radically different way of authenticating users, such as this. It seems that, to use that solution, I would need to re-write my code, and forgo the use of the traits, which include bonus features like login throttling and so on.
Is there a way I can redirect users based on role after login, while still using these built-in traits?
Im not sure if the 5.1 auth is the same as the 5.2 auth, but if it is, remove all that from the construct and add this method:
protected function handleUserWasAuthenticated( Request $request, $throttles, $guard )
{
if ($throttles) {
$this->clearLoginAttempts( $request );
}
if ( method_exists( $this, 'authenticated' ) ) {
return $this->authenticated( $request, Auth::guard( $guard )->user() );
}
return redirect()->intended( $this->redirectTo );
}
this is the method that will determine the redirect and you have access to the user object.
EDIT
I take the above back, just add the following to your controller;
protected function authenticated( $request, $user ) {
return redirect()->intended( $user->admin() ? '/admin' : '/client/dashboard' );
}
That should work nicely

Showing Wrong User Data CakePHP

I'm simply want to show the user that is currently logged in. My code for the Auth section came from 2.x cookbook.
The issue is the following:
I have 2 users currently in the system. User A and User B. User B was created second. Instead of showing the current user, it just shows User B. I assume it is because User B was the last to be created, because if I create User C, it will show user C instead.
Here is my action:
public function index($id = null) {
$this->set('strains', $this->Strain->find('all'));
$this->loadModel('User');
$users = $this->User->find('all');
$this->set('users', $users);
$this->set('userDataName', $this->Auth->user('id'));
if($this->Auth->user()) {
$this->User->id = $id;
$user = $this->Session->write('user', $this->User->findById($id));
$this->set('user', $user);
}
}
Here is the line in my view that should show the current user:
<?php echo $user['User']['username']; ?>
I've read several stack questions, but none seem to go over this specific scenario. I'm open to completely re-writing code if necessary. Thanks
the simplest way to display the username of the current session user is to use the auth component:
in controller
$user = $this->Auth->user(); // returns array with user data or null
$this->set('user', $user);
in view
echo $user['username'];
It's a logic error
Here is the line in my view that should show the current user:
<?php echo $user['User']['username']; ?>
In the template the username is taken from the $user variable.
public function index($id = null) {
...
$this->User->id = $id;
$user = $this->Session->write('user', $this->User->findById($id));
$this->set('user', $user);
}
}
The user variable depends on the $id parameter, not directly the currently logged-in user.
How to access the logged in user data
The simplest way to access the logged in user data is to use AuthComponent::user i.e. in a template:
<?php echo AuthComponent::user('username'); ?>

Getting the authenticated user details Laravel 5.2

After authenticating a user and return to an appropriate view I want to get hold of the id of the user so I can get some info from the table (users).
How do I do this please?
You can use Auth Facade in your controller to get the ID of authenticated user.
for eg.-
SomeController -
<?php
namespace App\Http\Controllers;
//don't forget to include this one
use Illuminate\Support\Facades\Auth;
class SomeController extends Controller
{
public function getDetails(){
//get authenticated user's Id
$user = Auth::user();
$user_id = $user->id;
//other details
$user_name = $user->name;
$user_email = $user->email;
}
}
You can use
Auth::user()->id or auth()->user()->id
If you have multiple authentication and you are using guard then you can use
Auth::guard('your_guard_name')->user()->id or auth()->guard('your_guard_name')->user()->id
N.B: if you use Auth then you must include it like use Auth
Hope it will help. :) :)

LARAVEL 5: Need to keep query string after auth redirects

I have a link I am sending via email. For example, www.swings.com/worker?id=3382&tok=jfli3uf
In this case I want the person to click the link, get sent to the login page(which it does) and then be directed to a controller method WITH the $id and $tok variables. I can't get that part to work. Any ideas? I am only using the RedirectIfAuthenticated class and this is what it looks like:
public function handle($request, Closure $next)
{
$user = $request->user();
if ($this->auth->check()) {
if($user && $user->hasRole('worker'))
{
return redirect('worker');
}
return redirect('home');
}
return $next($request);
}
hasRole is a method I created in the User model that checks the role of the logged in user
You can flash data to the session when redirecting by chaining the with() method:
// in your handle() method:
return redirect('home')->with($request->only('id', 'tok'));
// then in home controller method:
$id = session('id');
$tok = session('tok');
AFTER SOME HOURS I WAS ABLE TO HAVE A SOLUTION:
ReturnIfAuthenticated wasn't changed. I just added the following within my controller that this link should go to:
for instance, the route would be:
Route::get('worker', 'WorkerController#methodINeed');
Within this method:
public function methodINeed() {
$id = Input::get('id');
$tok = Input::get('tok');
// Do what I need this variables to do
}
What I didn't understand and what could not be properly understood is that the auth controller in Laravel 5 is triggered when a user is a guest it will still redirect to the actual method with all its original data once auth is successful. Hope this is helpful.

Accessing auth session data (Lithium + MongoDB)

Okay, so hopefully I am asking this question correctly:
I set up my user model & controller, as well as my session model and controller... but I want to render some of the session info onto a page.
for example
If I were to login to a page, it would read "Brian" (or whatever my username is that I used for my login)
I hope I am not asking a repeated question -- I have searched this question pretty extensively and haven't found a solution yet. Thanks a lot!
If your session (set in a config/bootstrap file) is called "default" then just run check ...
$user = Auth::check('default');
Then $user will have an array of the user data in the session, so if you have a first_name field in your database/session you could do:
echo $user["first_name"];
I created a helper to clean this up a little, I called it: extensions/helper/Login.php
<?php
namespace app\extensions\helper;
use lithium\security\Auth;
class Login extends \lithium\template\Helper {
public function user() {
$user = Auth::check('default');
return $user;
}
public function fullName() {
$user = self::user();
return $user["first_name"] . " " . $user["last_name"];
}
}
?>
Then in my Views I used it like ...
<?=$this->login->fullName(); ?>