I am new to laravel and I am working with a functionality where we insert data in user table with
DB::insert();
After that i get last id with
$user_id = DB::getPdo()->lastInsertId();
Now I want user to login after register and I am trying to
Auth::loginUsingId($user_id);
But its returning me false. I also tried
$user = User::find($user_id);
Auth::login($user);
Its also return null $user.
Please help...
This worked for me
Auth::loginUsingId(1);
Login User:
Auth::login($user);
check current user is login or not:
Auth::check();
Auth:login returns void so you can try something like this to check if user is logged in or not:
Auth::login($user);
return [
'status' => Auth:check()
];
check() determine if the current user is authenticated or not.
So, can you show your user Model?
In the Laravel Docs (https://laravel.com/docs/5.7/authentication) you can see, that your model must be an implementation of the Illuminate\Contracts\Auth\Authenticatable contract.
The basic User model looks like:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
and thats working lice expected.
Related
I am new to the laravel, i am implementing user registration api while registering the user it's throwing an error like mass_assignment
Add [first_name] to fillable property to allow mass assignment on [App\\Entities\\User].
User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
protected $table ='user';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'first_name','last_name','phone_number','email'
];
protected $guarded =[];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
UserController.php
public function userRegister(userRequest $request){
$data = $this->repository->create($request->all());
return $user = new UserTransformer($data);
}
}
please help why this error is happening ..?
The main problem is laravel5.8 the model paths are different so use following facade
use App\modelname
instead of use App\Entities\User,let me know if this resolves your problem :-)
what im trying to do is fetcing role data from single actions controller and got error messege when i test it out from postman. "message": "Call to undefined method App\Models\User::auth()", for anyone can give me hint or solution to fix this problems will highly appriciate. for further information im using jwt for auth, api as the guard.
so let me show you my code.
Controller:
<?php
namespace App\Http\Controllers\Api\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
class RoleController extends Controller
{
public function __invoke()
{
return User::auth()->user()->getRoleNames();
}
}
Model:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable implements JWTSubject
{
use HasFactory, Notifiable, HasRoles;
protected $guard_name = "api";
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'email',
'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function getJWTIdentifier(){
return $this->getKey();
}
public function getJWTCustomClaims(){
return [];
}
}
routes:
//group route with prefix "admin"
Route::prefix('admin')->group(function () {
//route login
Route::post('/login', [App\Http\Controllers\Api\Admin\LoginController::class, 'index']);
//group route with middleware "auth"
Route::group(['middleware' => 'auth:api'], function() {
//data user
Route::get('/user', [App\Http\Controllers\Api\Admin\LoginController::class, 'getUser']);
//refresh token JWT
Route::get('/refresh', [App\Http\Controllers\Api\Admin\LoginController::class, 'refreshToken']);
//logout
Route::post('/logout', [App\Http\Controllers\Api\Admin\LoginController::class, 'logout']);
Route::prefix('authorization')->group(function () {
Route::get('/roles', RoleController::class);// not working
});
});
});
There are few ways you can try for getting those roles:
shows all the role names
Auth::user()->roles
$roles = $user->getRoleNames(); // Returns a collection
check user has specific role
Auth::user()->hasRole('admin')
check user has any roles
Auth::user()->hasAnyRole(['super_admin', 'vendor'])
For other usage take a look at the site:
Spatie roles and permission info
I'm trying to use middlewares to protect Routes based on role.
Im testing with this route to allow only the role administrador to be able to enter it.
Route::get('/gestionarMedicos', [PersonaController::class,'mostrarMedicos'])->name('personaMostrarMedicos')->middleware('auth','firstLogin','role:administrador');
This is code of my middleware (in the route its the one called route)
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class EnsureUserHasRole
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next, $role)
{
if (! $request->user()->hasRole($role)) {
// Redirect...
return back();
}
return $next($request);
}
}
This is the code of the User model
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'role',
'name',
'email',
'password',
'idPersona',
'estado'
];
public function Persona(){
return $this->belongsTo(Persona::class,'idPersona');
}
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'remember_token'
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function hasRole($role)
{
return User::where('role', $role)->get();
}
}
Some logic is not done right because I can access the Route even with users that doesn't have that role
The dd() in the middleware was for testing, I get "administrador" with it.
I have tried Patrick Obafemi solution but I still have the same problem.
For testing I did a dd of what the if based on Patrcik answer result is and it is false.
I'm not sure where is the logic problem.
I'm also going to post a picture of my database model if it helps in some way.
The question is answered in the link below.
Middleware doesn't protect routes based on role
It also covers how to protect routes in the case you need to do it for multiple roles. The condition is wrong because it gives a collection of the users that have the role administrador. The condition should be like this to only allow a desired role to access the Route
if (!$request->user() || $request->user()->role != $role) {
// Redirect...
return back();
}
For multiple roles you can visit the link where the answer explains how to allow multiple desired roles to access the Route.
Maybe Patrick answer is right but question was also answered here.
I think your error is coming from your hasRole in your User Model. The result user() already has access to your user model so you can just make it a local scope. What you are doing now in your middleware will return something like this. So using the get function will return a collection of users but to check if that user exists you should use first() or better still exists(). Also you cannot call where on a single model entity and that's what $request->user()->role() is trying to do
User::User::where('role', $role)->get();
Try this instead
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class EnsureUserHasRole
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next, $role)
{
$id = $request->user()->id;
if (!User::where([['id', $id],['role',$role]])->exists()) {
// Redirect...
return back();
}
return $next($request);
}
}
Then your model will look like this
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'role',
'name',
'email',
'password',
'idPersona',
'estado'
];
public function Persona(){
return $this->belongsTo(Persona::class,'idPersona');
}
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'remember_token'
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function scopeRole($query, $role)
{
return $query->where('role', $role);
}
}
even your class diagram has a problem. if there are roles then there should be an inheritance. already how do you materialize this here. in short the solution is to make a gates or a policies or a middleware. i have an example of middleware but just for the verification if a user is admin.
class VerifyIsAdmin
{
public function handle($request, Closure $next)
{
$user = $request->user();
if ($user && $user->role === 'admin') {
return $next($request);
}
return abort(403);
}
}
this concerns the verifyIsAdmin middleware. then you go to
APP/Http/Kernel
then paste
protected $routeMiddleware = [
'admin' => VerifyIsAdmin::class,
];
and add the following line in the namespace
use App\Http\Middleware\VerifyIsAdmin;
and add to the route group
Route::middleware(['admin'])->group(function () {
So, first I hope my title is not misleading. Please let me know if my title fits the question.
QUESTION.
I'm using Laravel 5.3 and I'm trying to find a way to add an attribute "role" to Auth::user() so that I can access it like
Auth::user()->role.
Role is not a field in the user table used for authentication but it's a value I calculate to get. The reason I ask is I don't want to calculate role every single time I need the value, instead I want to set it when authentication succeeds then reuse it.
Any idea how I can do this?
Or is there any way I can persist a value through out the time a user is logged in so that I can calculate it once and reuse it?
The best way you can achieve this is in your User.php model:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token','is_admin',
];
protected function getRole(){
if(\Session::has("role")){
return Session::get("role");
}else{
//calculate and save role in session
}
}//end get Role
}//end class
so you will check it like this
Auth::user()->getRole();
Make sure you save the role in session after login , the getRole will get it and attach to the user() object , This doesnt need middleware too
Hope it helps
Just add the method of the keyword you want to use at the bottom of the model and use belongsTo() to link it up to a corresponding model. Then we just do Auth::user()->role() to use it. This is assuming you have a model called Role with a table and roles defined. (laravel 5.2+)
public function role() {
return $this->belongsTo( Role::class );
}
The entire model is here:
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
protected $guarded = ['id', 'remember_token'];
protected $hidden = [ 'password', 'remember_token' ];
public static $rules = array(
'email' => 'required|email|unique:users,email',
'first_name' => 'required|min:2',
'last_name' => 'required|min:2'
);
public static $rules_password = array(
'password' => 'required|min:6|confirmed'
);
public function role() {
return $this->belongsTo( Role::class );
}
}
I keep getting the method not found error when I'm trying to assign a role to the user in the user registration section.
The following is the code that I am using in the AuthController
namespace App\Http\Controllers\Auth;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\User;
class AuthController extends Controller
{
protected function create(array $data)
{
$user = User::create([
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'email' => $data['email'],
])->get();
$user->roles()->sync([2]);
return $user;
}
}
following is my User model
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Zizaco\Entrust\HasRole;
use App\Role;
class User extends Authenticatable
{
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $table = 'users';
protected $fillable = [
'first_name','last_name', 'email', 'password'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function roles()
{
return $this->belongsToMany('App\Role');
}
}
I'm not sure why this is happening. I think maybe it's not importing the User model properly, or I'm missing something. I'm new to laravel, so any help will be welcome.
To create a model simply use the following:
$user = User::create($attributes)
Notice that I did not call get() afterwords. get() will perform a query returning a Collection. I'm not sure what your Role model looks like, but it should work properly now.