Using spatie(laravel-permission) in Laravel 8 - laravel

When Assigning permission for a role using seeder, in permissions table it will take guard_name as "web",
but when adding permission through CRUD, it will take guard_name as "sanctum".
At the time of assigning this new permission to Role it will give an error.
RoleTableSeeder.php:
public function run()
{
DB::table('roles')->delete();
$roles_json = File::get("database/seeders/data/roles.json");
$perms_json = File::get("database/seeders/data/permissions.json");
$roles_data = json_decode($roles_json);
$perms_data = json_decode($perms_json);
Log::info("Starting Roles Population...");
foreach ($roles_data->roles as $role) {
$rl = Role::create([
'name' => $role->name,
'role_desc' => $role->role_desc
]);
$rol = Role::findOrFail($rl['id']);
foreach ($perms_data->permissions as $perm) {
$per = Permission::findOrFail($perm->id);
$rol->givePermissionTo($per);
}
Log::info("Populating... " . $role->name );
}
Log::info("Roles Populated Successfully.");
}
RoleController:
//---Assign Permission to Role
public function PermissionToRole($request, $id) {
$selectedRole = Role::find($id);
$selectedRolePermissions = $selectedRole->getAllPermissions();
$users = User::role($id)->get();
//---Remove Selected Role To Permissions
for ($i=0; $i < count($selectedRolePermissions); $i++) {
$selectedRole->revokePermissionTo($selectedRolePermissions[$i]);
}
if ($request->input('option') != null)
{
for ($k=0; $k < count($request->input('option')); $k++)
{
//---Insert New Permission To Role
$findPermission = Permission::find($request->input('option')[$k]);
$selectedRole->givePermissionTo($findPermission);
//---Remove Old Permissions From User & Assign New Permissions To Users
for ($m = 0 ; $m < count($users) ; $m++) {
for ($j = 0 ; $j < count($users[$m]->getDirectPermissions()) ; $j++) {
if ($findPermission->id == $users[$m]->getDirectPermissions()[$j]->id) {
$users[$m]->revokePermissionTo($users[$m]->getDirectPermissions()[$j]);
}
}
}
}
return back()->with('success', '');
}
}//---End of Function PermissionToRole
How to get both guard_name as "web" not "sanctum" because when assigning this permission to Role I get an error:
routes/web.php
Route::get('pertorole/{role_id}', 'Roles\RoleController#PerToRoleEdit')->name('role.pertoroleedit')->middleware('can:Assign Permission');
Route::patch('pertorole/{role_id}', 'Roles\RoleController#PerToRoleUpdate')->name('role.pertoroleupdate')->middleware('can:Assign Permission');
app/Http/Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Laravel\Jetstream\Http\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\Localization::class,
],
'api' => [
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,
'permission' => \Spatie\Permission\Middlewares\PermissionMiddleware::class,
'role_or_permission' => \Spatie\Permission\Middlewares\RoleOrPermissionMiddleware::class,
];
}

add protected $guard_name = 'web'; to your User model.
sanctum default guard is "web".

Related

How to fix laravel middleware

Laravel middle-ware keeps redirecting me to welcome page even if the user is an admin. what i want is if a user is an admin,then he/she can view the routes for the admin, otherwise the user should be redirected to the root page "('/').
I believe i have done everything correctly but somehow i can not view the admin pages, i am redirected to the root page even if a user is an admin.
please assist me fix this bug.
Admin middle-ware class
class Admin
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(Auth::user()->isAdmin()){
return $next($request);
}
return redirect('/');
}
}
User Model
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'role_id','photo_id','gender'
];
/**
* 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',
];
//A role Belongs to a User//
public function role(){
return $this->belongsTo('App\Role');
}
public function photo(){
return $this->belongsTo('App\Photo');
}
public function isAdmin(){
if($this->role->name =='Administrator'){
return true;
}
return false;
}
}
Routes(web.php)
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Auth::routes();
Route::group(['middleware'=>'web'],function(){
Route::get('/', function () {
return view('welcome');
});
Route::get('/', [
'uses'=>'HomeController#index',
'as'=>'welcome'
]);
});
Route::group(['middleware'=>['admin']],function(){
Route::resource('/admin/users','AdminUsersController');
Route::get('admin',[
'uses'=>'AdminUsersController#dashboard',
'as'=>'admin.index'
]);
Route::get('admin/users',[
'uses'=>'AdminUsersController#index',
'as'=>'admin.users'
]);
Route::get('admin/users/edit/{id}',[
'as'=>'admin.users.edit',
'uses'=>'AdminUsersController#edit'
]);
Route::get('admin/users/create',[
'as'=>'admin.users.create',
'uses'=>'AdminUsersController#create'
]);
});
Kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'admin' => \App\Http\Middleware\Admin::class,
];
}

Session is not working as expected

Following is my middleware where I am setting some content on every request. For example cms_content in 'cms' session which I need to access in a helper to show the content in blade template.
<?php
namespace App\Http\Middleware;
use App\Repositories\EloquentCountryRepository;
use App\Repositories\EloquentCmsContentRepository;
use Closure;
use Location;
use Session;
class SetDefaultLanguage
{
// Instance of App\Repositories\EloquentCountryRepository;
public $country;
// Instance of App\Repositories\EloquentCmsContentRepository;
public $cmsContent;
/**
*
* Initialize dependencies
*/
public function __construct(EloquentCountryRepository $country, EloquentCmsContentRepository $cmsContent)
{
$this->country = $country;
$this->cmsContent = $cmsContent;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
//$location = Location::get(request()->ip());
//$location = Location::get('146.185.171.157'); // Netherlands IP
$location = Location::get('103.255.106.250'); // Indian IP
$country = $this->country->getCountryByCode($location->countryCode);
if($country->language_id){
$contents = $this->cmsContent->getContentByLanguageId($country->language_id);
}
if($contents->isEmpty()){
$contents = $this->cmsContent->getContentByLanguageId(1); // Default id for English
}
$contents = $contents->toArray();
foreach($contents as $content){
$cms[$content['meta_key']] = $content['meta_value'];
}
// Store CMS content into session
session(['cms' => $cms, 'country_id' => $country->id]);
//dd(session('cms'));
return $next($request);
}
}
Following is my helper method where i am accessing session data which i set in middleware.
public static function showDefault($key, $default_text = NULL){
if(isset(session('cms')[$key])){
return session('cms')[$key];
}else{
return $default_text;
}
}
When I dd() session on the same middleware it seems working but in helper it is not showing latest data which i have set in middleware.
Please help me out this, i am trying to solve this issue since last 2 hours but dint get any solution.
Finally i found the solution when i move my SetDefaultLanguage middleware from $middleware to web $middlewareGroups
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\SetDefaultLanguage::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
}

"Unauthenticated" error on a route that is not protected

Part of my application does not utilize standard user authentication, and lies outside the auth group in my routes file. I am using Laravel Passport, VueJS2, VueRouter. Laravel is serving two blade files; one for the authenticated part of the application, and the other for the non-authenticated part.
However, I find that when trying to access that part of the application, it still requires me to be authenticated (I get the 401: Unauthorized error).
I have looked through my configuration files, and I can't seem to figure out why this would be displayed.
My api.php file:
<?php
use Illuminate\Http\Request;
Route::group(['middleware' => 'auth'], function () {
// A lot of routes here...
});
// These should not be guarded
// This is the route that triggers the unauthenticated message
Route::post('authenticate', 'TestController#authenticate');
THe JS file that makes the request:
authenticateUser: function() {
var data = {
'id' : this.$route.params.id,
'passcode' : this.state.password,
};
var that = this;
axios({
method: 'post',
url: '/api/authenticate',
withCredentials: true,
data: data,
}).then(function(response) {
swal('Great!', 'You have been authenticated.', 'success');
that.$router.push('/client/create/' + that.$route.params.id);
}, function(error) {
swal('Woah!', 'Wrong password, go away.', 'error');
});
}
Here is my kernel.php file:
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'test.auth' => \App\Http\Middleware\VerifyTestAccess::class,
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'test.state' => \App\Http\Middleware\VerifyTestState::class,
];
}

Laravel 5.3 :How To use Check Auth in Global Middleware?

I want show the number of unread messages in the header of my site and a few other views. For this I wrote a global middleware, but this middleware can not access of auth info of the signed up user.
<?php
namespace PTA_OIMS\Http\Middleware;
use Illuminate\View\Factory;
use Closure;
use Illuminate\Contracts\Auth\Guard;
use PTA_OIMS\Kartable;
use Session;
class UnreadMessage
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
protected $auth;
protected $view;
public function __construct(Guard $auth, Factory $view)
{
$this->auth = $auth;
$this->view = $view;
}
public function handle($request, Closure $next)
{
$unreadMessage = NULL;
$user = $this->auth->check();
if (!empty($user)) {
$unreadMessage = Kartable::
where('id_reciver', '=',
Session::get('personnel_info.0')->box_id)
->whereBetween('status', [1, 2])
->where('view_date', '=', Null)
->count();
}
$this->view->share('unreadMessage', $unreadMessage);
return $next($request);
}
}
UPDATE:
<?php
namespace PTA_OIMS\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\PTA_OIMS\Http\Middleware\UnreadMessage::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\PTA_OIMS\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\PTA_OIMS\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \PTA_OIMS\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
}
Try to use global auth() helper:
$user = auth()->check();

Call to a member function set() on null

I am trying to use oauth for google in laravel 5 but i am getting the error. Can any one help me to sort out this problem.
Followings are my files please check out
.env
GOOGLE_ID = 'mygoogleId'
GOOGLE_SECRET = 'mysecretID'
GOOGLE_REDIRECT = http://localhost:8090/users
services.php
'google' => [
'client_id' => env('GOOGLE_ID'),
'client_secret' => env('GOOGLE_SECRET'),
'redirect' => env('GOOGLE_REDIRECT'),
],
AuthController
public function redirectToProvider() {
return Socialite::driver('google')->redirect();
}
public function handleProviderCallback() {
$user = Socialite::driver('google')->user();
console.log($user);
}
routes.php
Route::get('google', 'Auth\AuthController#redirectToProvider');
Route::get('google/callback', 'Auth\AuthController#handleProviderCallback');
//I have set the providers and aliases in app.php.
Here is the code where i am getting an error
//on set() method
public function redirect()
{
$state = str::random(40);
if ($this->usesState()) {
$this->request->getSession()->set('state', $state);
}
return new RedirectResponse($this->getAuthUrl($state));
}
Thanks in advance..
Hey If you are using laravel 5.2, this is worked for me.
Put your controllers in 'web' middleware. like,
Route::group(['middleware' => 'web'], function() {
Route::get('google', 'Auth\AuthController#redirectToProvider');
Route::get('google/callback', 'Auth\AuthController#handleProviderCallback');
});
and Make sure Kernel file has middleware classes registered.
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\Perkweb\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Perkweb\Http\Middleware\VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
],
];

Resources