I've two types of users in my application. 'admins' & 'frontend users'. 'admin' has roles. i want redirect admins according to their roles. i've done the multiauth system but don't know how to redirect admins according to their roles.
here is admin model ->
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
use Notifiable;
protected $guard = 'admin';
/**
* 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',
];
// public function post(){
// return $this->hasOne('App\Post');
// }
public function role()
{
return $this->belongsTo('App\Role');
}
}
here is role model ->
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
public function admins()
{
return $this->hasMany('App\Admin');
}
}
here is the login controller for admins ->
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Auth;
use App\Admin;
use App\Role;
class BackendLoginController extends Controller
{
use AuthenticatesUsers;
public function __construct()
{
$this->middleware('guest:admin', ['except' => ['logout']]);
}
public function showLoginForm()
{
return view('backEnd.backEnd-login');
}
public function login(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
if(Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->remember))
{
return redirect()->intended(route('dashboard'));
}
return redirect()->back()->withInput($request->only('email', 'remember'));
}
public function logout()
{
Auth::guard('admin')->logout();
return redirect('/');
}
}
here is the login controller for users ->
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Auth;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => ['logout', 'userLogout']]);
}
public function userLogout()
{
Auth::guard('web')->logout();
return redirect('/');
}
}
routes ->
Route::get('/backend-login', 'Auth\BackendLoginController#showLoginForm')->name('backend.login');
Route::post('/backend-login', 'Auth\BackendLoginController#login')->name('backend.login.submit');
Route::get('/dashboard', 'BEController#index')->name('dashboard');
Route::get('/logout', 'Auth\BackendLoginController#logout')->name('backend.logout');
i've made guards and done the multiauth but can't set the role base system natively
Related
I want to create users with factories and directly assign roles to them. However, I encountered an error while seeding.
My Error was like there :
Method Illuminate\Database\Eloquent\Collection::assignRole does not exist.
Here is the code from my databaseSeeder.php :
$user = User::factory(10)->create()->assignRole('Admin');
That is my UserFactory code. This is default, I dont change anithing:
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
/**
* #extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class UserFactory extends Factory
{
/**
* Define the model's default state.
*
* #return array<string, mixed>
*/
public function definition()
{
return [
'name' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
/**
* Indicate that the model's email address should be unverified.
*
* #return static
*/
public function unverified()
{
return $this->state(fn (array $attributes) => [
'email_verified_at' => null,
]);
}
}
This is my user model:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles;
use PHPOpenSourceSaver\JWTAuth\Contracts\JWTSubject;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;
class User extends Authenticatable implements JWTSubject, HasMedia
{
use HasApiTokens, HasFactory, Notifiable, HasRoles, InteractsWithMedia;
/**
* The attributes that are mass assignable.
*
* #var array<int, string>
*/
protected $fillable = [
'name',
'e-mail',
'passwords',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Please help me, Thanks!
Try assigning the role in your User factory callback like so:
class UserFactory extends Factory
{
...
public function configure()
{
return $this->afterCreating(function (User $user) {
$user->assignRole('Administrator');
});
}
...
This method will be automatically run when you run the factory. After each create it will run assignRole on the created User model.
Use the factory like so:
User::factory()->count(10)->create();
https://laravel.com/docs/8.x/database-testing#factory-callbacks
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 am trying to get all user in my table but I get an error 403 user does not have the necessary rights. I am using laratrust and vuejs. I have already logged in as a superadministrator. This is my controller class
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\user;
use Illuminate\Support\Facades\Hash;
class UserController extends Controller
{
public function __construct()
{
$this->middleware('role:user|superadministrator');
}
public function index()
{
return view('user.index');
}
public function getusers(){
$theUser = Auth::user();
if ($theUser->hasRole('superadministrator')) {
return $users;
}
}
}
My api route
Route::get('/allusers','UserController#getusers');
I have tried to go through the documentation but no success.Kindly help me solve this issue
User Model
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laratrust\Traits\LaratrustUserTrait;
class User extends Authenticatable
{
use LaratrustUserTrait;
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',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
What about if you try this:
public function getusers(Request $request){
$theUser = $request->user('api');
if ($theUser->hasRole('superadministrator')) {
return $users;
}
}
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.
I am using Laravel 5.3 in which using Authfor user controller.
So basically i create a Listener for Auth Event
'Illuminate\Auth\Events\Login' => [
'App\Listeners\LogSuccessfulLogin',
],
and in LogSuccessfulLogin handle() function redirecting user on basic of role. but my redirecting function is not working. Its render the default page '\home' route.
I am sharing My Files :-
EventServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* #var array
*/
protected $listen = [
'App\Events\SomeEvent' => [
'App\Listeners\EventListener',
],
'Illuminate\Auth\Events\Login' => [
'App\Listeners\LogSuccessfulLogin',
],
];
/**
* Register any events for your application.
*
* #return void
*/
public function boot()
{
parent::boot();
//
}
}
Route/web.php
<?php
//Auth::routes();
Route::get('logout', function(){
Auth::logout(); // logout user
return Redirect::to('/');
});
#Route::get('/', 'HomeController#index')->name('homepage');
Route::get('/', function () {return view('welcome');});
Route::group(['middleware' => ['auth', 'checkrole:Admin'],'namespace' => 'Admin','prefix' => 'admin'], function () {
Route::get('/123','DashboardController#index')->name('dashboard');
#Route::get('/','DashboardController#index')->name('dashboard');
Route::get('user/profile', function () {
// Uses Auth Middleware
});
});
and here is LogSuccessfulLogin.php
<?php
namespace App\Listeners;
use Illuminate\Auth\Events\Login;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
class LogSuccessfulLogin
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param Login $event
* #return void
*/
public function handle(Login $event)
{
$user=Auth::User()->role->role_name;
if($user=="Admin"){
return Redirect::route('dashboard');
#return redirect()->route('login');
}
elseif($user == "Employer" ){
dd("hello");
}
}
}
and this is the default logincontroller of Auth
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'logout']);
}
}
Please let me know if i am doing some wrong.
Actually i also tried in LogSuccessfulLogin Listener for redirect the page with return redirect()->route('login'); but its also not working.
As one of possible solutions I would provide a response middleware that will be attached to login route. After getting response you should check if user is logged and if yes - apply your custom redirection login. In that case you will overwrite default Laravel 5.3 logic of redirection. Smth like this:
class PostLoginMiddleware
{
public function handle($request, Closure $next, $guard = null)
{
// here you've already have response and it's usually redirect
$response = $next($request);
// if user logged in
if (\Auth::id()) {
$customRedirectResponse = // ...apply your custom logic
return $customRedirectResponse;
}
return $response;
}
}
You should define this middleware in app/Http/Kernel.php in
protected $routeMiddleware = [
'custom-redirect' => \YourNamespace\PostLoginMiddleware::class
];
And then apply it on login route
/* Authentication Routes */
$this->get('login', 'Auth\AuthController#showLoginForm');
$this->post('login', ['middleware' => 'custom-redirect', 'uses' => 'Auth\AuthController#login']);
$this->get('logout', 'Auth\AuthController#logout');