Permission issue in Laravel - laravel

I am facing problem regarding permission
Argument 1 passed to App\Providers\AuthServiceProvider::App\Providers{closure}() must be an instance of App\Providers\User, instance of App\User given, called in C:\xampp\htdocs\Tweety\vendor\laravel\framework\src\Illuminate\Auth\Access\Gate.php on line 473 (View: C:\xampp\htdocs\Tweety\resources\views\tweet.blade.php)
I am just working to show delete button only on those tweets made by the authenticated users
my controller
public function destroy(Tweet $tweet)
{
$tweet->delete();
Session::flash('success');
return redirect()->route('tweets.index')->with(['message' => 'Tweet Deleted']);
}
my user model
public function tweets()
{
return $this->hasMany(Tweet::class)->latest();
}
my blade
#can('delete',$tweet)
<form action="{{ route('tweets.destroy',$tweet->id) }}" method="POST">
#csrf
#method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
#endcan
AuthServiceProvider
public function boot()
{
$this->registerPolicies();
Gate::define('delete', function (User $user , Tweet $tweet){
return $tweet->user->is($user);
});
}
Any help will be appreciated

It looks like a namespace issue and didn't import User model's namespace correctly.
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use App\User; // looks like you're missing this line.
use App\Tweet;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* #var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* #return void
*/
public function boot()
{
$this->registerPolicies();
Gate::define('delete', function (User $user , Tweet $tweet){
return $tweet->user->is($user);
});
}
}

You would need to change:
#can('delete', $tweet)
to:
#can('delete')

Related

Laravel Fortify Logout Redirect

Hello guys is there any ways to redirect the logout function of Fortify?
<div class="nav-link" id="nav-bar-logoutbutton">
<form method="POST" action="{{ route('logout') }}">
#csrf
<button class="btn btn-secondary btn-sm" type="submit">Logout</button>
</form>
</div>
this is my blade logout
You can do the following:
Create a new LogoutResponse class and implement your redirect logic into the toResponse method:
"app/Http/Responses/LogoutResponse.php"
<?php
namespace App\Http\Responses;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Laravel\Fortify\Contracts\LogoutResponse as LogoutResponseContract;
use Symfony\Component\HttpFoundation\Response;
class LogoutResponse implements LogoutResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* #param Request $request
*
* #return Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? new JsonResponse('', 204)
: redirect('www.example.com');
}
}
Now you can bind the new response into the service container in the boot method of your FortifyServiceProvider:
"app/Providers/FortifyServiceProvider.php"
public function boot()
{
$this->app->singleton(
\Laravel\Fortify\Contracts\LogoutResponse::class,
\App\Http\Responses\LogoutResponse::class
);
}
In your config/fortify.php, add:
'redirects' => [
'logout' => 'login',
],
Just create a new post request in your routes/web.php
Route::post('logout', [ClientController::class, 'logout'])->name('logout');
Now in your controller, create a function to handle the request, make sure to include the Auth class at the top.
use Auth;
/* Process the logout request */
public function logout(Request $request) {
Auth::logout();
return redirect('/login')->with(['msg_body' => 'You signed out!']);
}
Instead of /login, you can redirect to anywhere.

Use Auth in AppServiceProvider

I need the ID of the user who is logged in to get a photo in the profile table, here I am trying to use View but only in the index function that gets $profile, I want all files in the view to have $profile
public function index(){
$profil = Profil_user::where('user_id',$auth)->first();
View::share('profil', $profil);
return view('user.index');
}
I have also tried AppServiceProvider but I get an error in the form of a null value if I don't log in, is there a solution to my problem?
public function boot(){
$auth = Auth::user();
dd($auth);
}
exist several way to pass a variable to all views. I explain some ways.
1. use middleware for all routes that you need to pass variable to those:
create middleware (I named it RootMiddleware)
php artisan make:middleware RootMiddleware
go to app/Http/Middleware/RootMiddleware.php and do following example code:
public function handle($request, Closure $next) {
if(auth()->check()) {
$authUser = auth()->user();
$profil = Profil_user::where('user_id',$authUser->id)->first();
view()->share([
'profil', $profil
]);
}
return $next($request);
}
then must register this middleware in app/Http/Kernel.php and put this line 'root' => RootMiddleware::class, to protected $routeMiddleware array.
then use this middleware of routes or routes group, for example:
Route::group(['middleware' => 'root'], function (){
// your routes that need to $profil, of course it can be used for all routers(because in handle function in RootMiddleware you set if
});
or set for single root:
Route::get('/profile', 'ProfileController#profile')->name('profile')->middleware('RootMiddleware');
2. other way that you pass variable to all views with view composer
go to app/Http and create Composers folder and inside it create ProfileComposer.php, inside ProfileComposer.php like this:
<?php
namespace App\Http\View\Composers;
use Illuminate\View\View;
class ProfileComposer
{
public function __construct()
{
}
public function compose(View $view)
{
$profil = Profil_user::where('user_id', auth()->id)->first();
$view->with([
'profil' => $profil
]);
}
}
now it's time create your service provider class, I named it ComposerServiceProvider
write this command in terminal : php artisan make:provider ComposerServiceProvider
after get Provider created successfully. message go to config/app.php and register your provider with put this \App\Providers\ComposerServiceProvider::class to providers array.
now go to app/Providers/ComposerServiceProvider.php and do like following:
namespace App\Providers;
use App\Http\View\Composers\ProfileComposer;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
View::composer(
'*' , ProfileComposer::class // is better in your case use write your views that want to send $profil variable to those
);
/* for certain some view */
//View::composer(
// ['profile', 'dashboard'] , ProfileComposer::class
//);
/* for single view */
//View::composer(
// 'app.user.profile' , ProfileComposer::class
//);
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
}
}
3. is possible that without create a service provider share your variable in AppServiceProvider, go to app/Provider/AppServiceProvider.php and do as follows:
// Using class based composers...
View::composer(
'profile', 'App\Http\View\Composers\ProfileComposer'
);
// Using Closure based composers...
View::composer('dashboard', function ($view) {
//
});
I hope be useful
you can use this
view()->composer('*', function($view)
{
if (Auth::check()) {
$view->with('currentUser', Auth::user());
}else {
$view->with('currentUser', null);
}
});

How to debug this error 'The GET method is not supported for this route. Supported methods: POST.'?

I am trying to work with forms in laravel but I keep getting this error
Symfony \ Component \ HttpKernel \ Exception \
MethodNotAllowedHttpException The GET method is not supported for this
route. Supported methods: POST.
I have tried so many ways to solve it but ain't solving it
Here my model
create_posts_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePostsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->string('caption');
$table->string('image');
$table->timestamps();
$table->index('user_id');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
}
post.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model {
protected $fillable = ['caption', 'image'];
public function user(){
return $this->belongsTo(User::class);
}
}
Controller PostsController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostsController extends Controller
{
public function create(){
return view('posts.create');
}
public function store(Request $request){
$request->validate([
'caption' => 'required',
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg',
]);
Post::create($request->input());
dd($request->all());
}
}
Routes web.php
<?php
/*
|--------------------------------------------------------------------------
| 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!
j|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/p/create', 'PostsController#create');
Route::post('/p', 'PostsController#store')->name('p.store');
Route::get('/profile/{user}', 'ProfilesController#index')->name('profile.show');
Blade file:
<div class="container"> <form action="/p" enctype="multipart/form-data" method="post"> #csrf
Kindly Help me, I've been stack for 3 days because of that above error .
In the browser I have this
protected function methodNotAllowed(array $others, $method)
{
throw new MethodNotAllowedHttpException(
$others,
sprintf(
'The %s method is not supported for this route. Supported methods: %s.',
$method,
implode(', ', $others)
)
);
}
Edit: According to your comment, your <form> appears to be correct. Could you provide the Envoirement Details that you see on the Whoops! page? They can be found int the bottom right corner.
I assume that you have a html form from which you acces your PostsController. Your tag should look something like this: <form action="{{route('p.store')}}" method="post". You probably have method="get". If so, change the method to post, that should work.

Laravel | Auth::user()->id isn't working in AppServiceProvider

I can get the Auth ID when i put it in any controller with
Auth::user()->id
But when i put it in AppServiceProvider.php , it returns `Trying to get property 'id' of non-object
i don't understand why ?
Eddit : I tried this but still not working
public function boot()
{
view()->composer('*', function ($view)
{
if (Auth::check())
{
$id=Auth::user()->id;
$idd=Person::where('user_id','=',$id)->get('photo');
$view->with('idd', $idd );
$view->with('id', $id );
}
});
}
Error :
Argument 1 passed to Illuminate\Database\Grammar::columnize() must be of the type array, string given, called in
To get the currently authenticated user's ID, use
Auth::id();
Another case may be that there is not a current user, in which case Auth::user() is returning NULL. Wrap the code in a
if (Auth::check())
{
// Do stuff
}
to make sure there is a user logged in.
view()->composer('*', function($view)
{$view->with('user',auth()->user());
});
it's work for me
<?php
namespace Fitness\Providers;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot(Request $request)
{
view()->share('user', $request->user());
}
}

HttpException in Handler.php line 107: This action is unauthorized

I'm learning Laravel 5. I have finished the document's Quickstart - intermediate. I want to apply the authorize check for Task's actions to the User's. I want to check whether the target user is the current logged in user in order to use user's edit action. However, browser keeps telling me when I try to access http://myfirst.app/users/2/edit:
FatalThrowableError in UsersPolicy.php line 20:
Type error: Argument 1 passed to App\Policies\UsersPolicy::edit() must be an instance of Illuminate\Http\Request, instance of App\User given
Routes.php
Route::get('/users/{user}', 'UsersController#view');
Route::get('/users/{user}/edit', 'UsersController#edit');
Route::patch('/users/{user}', 'UsersController#update');
AuthServiceProvider.php
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
'App\Task' => 'App\Policies\TaskPolicy',
'App\User' => 'App\Policies\UsersPolicy',
];
UsersPolicy.php
namespace App\Policies;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Auth\Access\HandlesAuthorization;
class UsersPolicy
{
use HandlesAuthorization;
public function edit(Request $request, User $user)
{
return $request->user()->id === $user->id;
}
public function update(Request $request, User $user)
{
return $request->user()->id === $user->id;
}
}
UsersController.php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class UsersController extends Controller
{
protected $user;
public function __construct() {
$this->middleware('auth');
}
public function view(Request $request, User $user)
{
if($request->user()->id == $user->id){
return view('users.view', ['user' => $user]);
}
return redirect('/tasks');
}
public function edit(Request $request, User $user)
{
$this->authorize('edit', $user);
return view('users.edit', compact('user'));
}
public function update(Request $request, User $user)
{
$this->authorize('update', $user);
$user->update($request->all());
return redirect('/users/'.$user->id);
}
}
In the Document's TaskController's delete function, $user isn't passed into $this->authorized('destroy', $task) in order to allow TaskPolicy's destroy function to use $user:
TaskController.php
public function destroy(Task $task)
{
$this->authorize('destroy', $task);
$task->delete();
return redirect('/tasks');
}
TaskPolicy.php
public function destroy(User $user, Task $task)
{
return $user->id === $task->user_id;
}
Anyway, I followed the exception and added $request to UsersController's edit function's parameter
$this->authorize('edit', $request, $user);
And I get
HttpException in Handler.php line 107:
This action is unauthorized.
What should I do?
In your Request file set
public function authorize()
{
return true;
}
Try this: in UsersPolicy.php add:
enter code here/**
* #var User
*/
protected $user;
/**
* Create a new policy instance.
*
* #param User $user
*/
public function __construct(User $user)
{
$this->user = $user;
}
And in your UsersController.php change $this->authorize('edit', $user); to $this->authorize('edit');
Hope that helps
as per documentation: "The Gate will automatically return false for all abilities when there is not an authenticated user". So before doing any authorization, please check Auth::user() if it returns a currently authenticated user.

Resources