1

I create a policy called LetterPolicy , this is the code

    namespace App\Policies;

    use App\Letter;
    use App\User;
    use Illuminate\Auth\Access\HandlesAuthorization;

    class LetterPolicy
    {
        use HandlesAuthorization;

        /**
         * Create a new policy instance.
         *
         * @return void
         */

        public function __construct()
        {
            //
        }

        public function update(User $user, Letter $letter)
        {
            return($user->id === $letter->user_id || $user->role_id===1 ) ;
        }
    }

and this is authserviceprovider

namespace App\Providers;

use App\Letter;
use App\Policies\LetterPolicy;
use App\Policies\UserPolicy;
use App\User;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        'App\Model' => 'App\Policies\ModelPolicy',
        User::class => UserPolicy::class,
        Letter::class => LetterPolicy::class,
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
        //
    }
}

And in the following code I check for the user

class LetterController extends Controller
{
protected $user;
public function __construct()
{
    $this->middleware(function ($request, $next){
       $this->user = Auth::user();
        return $next($request);
    });

}
public function edit(Letter $letter)
{
    if($this->user->can('update', $letter)){           
       //edit
    }
    else
        abort('403', 'Access Denied');
}

The code is working well in localhost but on the remote server it reports the access denied error. I created this policy after deploying the site on the server so I create a route /clear-cache with code

    Route::get('/clear-cache', function() {
        $exitCode = \Illuminate\Support\Facades\Artisan::call('cache:clear');
    });

To clear the cache after creating the policy. But it still reports the 403 error. What is the problem?

Roman Hocke
  • 4,137
  • 1
  • 20
  • 34
M a m a D
  • 1,938
  • 2
  • 30
  • 61
  • Check th permissions of Policy Class file and also try running composer dump-autoload – Syed Faisal Aug 19 '18 at 08:36
  • @SyedFaisal How can I run composer on server? – M a m a D Aug 19 '18 at 08:41
  • Do you have ssh access to the server?? – Syed Faisal Aug 19 '18 at 08:43
  • yes I have access – M a m a D Aug 19 '18 at 08:44
  • Login to your server using ssh, you can use putty for windows and terminal for linux, navigate to your project directory, will be in /var/www/ or public_html if you are using cpannel, and try to run composer – Syed Faisal Aug 19 '18 at 08:47
  • @SyedFaisal I manually upload the vendor and composer and composer.lock to server. the error still persists – M a m a D Aug 19 '18 at 10:02
  • 2
    Is the user can actually edit the letter? Maybe your data is wrong and policy works correct? – Ozan Kurt Aug 19 '18 at 10:43
  • @OzanKurt yes it can – M a m a D Aug 19 '18 at 21:12
  • @OzanKurt I tried `dd($this->user->id === $letter->user_id || $this->user->role_id===1 );` and it returned `false`. I tried `dd($this->user->id == $letter->user_id || $this->user->role_id==1 );` and it was `true`. Now it works but I don't know why!!! – M a m a D Aug 19 '18 at 21:17
  • @SyedFaisal I tried `dd($this->user->id === $letter->user_id || $this->user->role_id===1 );` and it returned `false`. I tried `dd($this->user->id == $letter->user_id || $this->user->role_id==1 );` and it was `true`. Now it works but I don't know why!!! – M a m a D Aug 19 '18 at 21:17

2 Answers2

2

I tried dd($this->user->id === $letter->user_id || $this->user->role_id===1 ); in the COntroller and it returned false. I tried dd($this->user->id == $letter->user_id || $this->user->role_id==1 ); and it was true. Now it works but I don't know why!!!

M a m a D
  • 1,938
  • 2
  • 30
  • 61
  • 2
    You did `===` instead of `==`. Using `===` will enforce same type comparison and will not do hidden type casting as the `==` does. Take a look at [this question](https://stackoverflow.com/questions/80646/how-do-the-php-equality-double-equals-and-identity-triple-equals-comp) Apparently or `$this->user->id` and `$letter->user_id` are not of the same type or `$this->user->role_id` is not an integer. By using `==` it does not compare types, so then it will return true. Try to `dd()` the variables, then you can see the types in the browser. – Fjarlaegur Aug 20 '18 at 10:04
2

Fjarlaegur's answer was the key. I had the same problem: in localhost there was no issue, but in production server somehow every authorization failed and it was because of the comparison operator. Changed from === to == and all as good.

Carlos
  • 93
  • 2
  • 7