I have created a review blade for restaurants i need it to save the restaurants id .i have a variable called restaurant_id which stores the restaurants review comment.This is my review blade
<html>
{!!Form::open(['action' =['ReviewsController#store'],'method'=>'POST','enctype'=>'multipart/form-data'])!!}
<div class="form-group">
{{Form::textarea('value',null,['id'=>'value','placeholder'=>'Insert
here','name'=>'value'])}}
</div>
{{Form::submit('submit',['class'=>'btn btn-
primary','type'=>'submit','id'=>'submit'])}}
{!!Form::close()!!}
</html>
i also have user_id which stores the id the currently logged in user but it gives me an error
ErrorException (E_NOTICE)
Trying to get property 'id' of non-object
This is the review controller function that stores the review
public function store(Request $request )
{
// $restaurant=Restaurant::find($id);
$review=new Review;
$review->user_id=auth()->user()->id;
$review->restaurant_id=$request->route('id');
$review->value=$request->input('value');
$review->save();
}
This is the link to the review blade template on the restaurant
Add review
$review->user_id=auth()->user()->id;
This line assumes the existence of a logged in user. If your application supports reviews from non-authenticated users, you need to account for auth()->user() being null instead of a User object:
$review->user_id = auth()->user() ? auth()->user()->id : null;
Your code, specifically:
auth()->user()->id;
is assuming there is always an authenticated user. Currently there isn't, therefore you are:
Trying to get property 'id' of non-object
since auth()->user() is a non-object and you're attempting to get the property id from it.
You will have to do some kind of authentication check assuming you only want authenticated users doing what you want done.
public function store(Request $request)
{
if (! Auth::check() {
// Do something here if the user isn't authenticated, such as
// return back()->withInput();
}
$review = new Review;
$review->user_id = auth()->user()->id;
$review->restaurant_id = $request->route('id');
$review->value=$request->input('value');
$review->save();
}
Related
I'm a newbie who is learning Laravel 7. I have developed a small web application with Laravel 7. But today I noticed one problem. That all the URLs are global, means all users can access all the URLs of my website. Suppose User A created data and it shows in a table where the edit and delete buttons exist with every row. The edit URL is like: localhost/records/edit/5. The problem is, that other logged-in users can access this edit page also. Like this, all the URLs are accessible by any logged-in users which is very bad.
I hope you understand what I'm saying. I have almost 250+ web routes. Is there any easy way to restrict the routes?
User can access their own data only. How can I do that?
Thanks
You'll have to register policies and ensure users cannot access parts of the website without the correct authorization.
See the docs on how to write policies and implement them.
Sample code:
Policy:
class RecordPolicy
{
public function delete(User $user, Record $record)
{
return $user->id === $record->user_id;
}
}
Controller
class RecordController
{
public function destroy(Record $record)
{
// Authorize the delete action before actually deleting the record
$this->authorize('delete', $record);
$record->delete();
}
}
Records index
#foreach($records as $record)
<div>
{{ $record->name }}
{{-- Only show delete button if the authorized user can actually delete the record --}}
#can('delete', $record)
<form action="{{ route('records.destroy', compact('record') }}" method="POST">
#csrf
#method('DELETE')
<button type="submit">Delete record</button>
</form>
#endcan
</div>
#endforeach
store user_id when new record added > Add created_by field in user_table DB
when user run URL > get logged-in user user_id from session and check in DB for their record > if record not found then redirect to home page with message otherwise continue.
If i understand you correctly you want to restrict routes to specific user.
Create a roles table
Columns (id, name)
(1 = Super Admin, 2 = Admin, 3 = User)
Assign Roles To User While Creating new User
i.e add role_id to users table.
$user = User::create([
'name' => 'First Admin',
'email' => 'admin#admin.com',
'password' => Hash::make('Admin#1234'),
'role_id' => 2 // For admin role
]);
Then Create Middlewares for each role and restrict routes for specific users.
Admin Middleware: AdminMiddleware.php
public function handle(Request $request, Closure $next)
{
$allowedRoles = [2];
if (!in_array(Auth::user()->role_id, $allowedRoles))
{
return redirect()->back()->with('error',__('Sorry, you are not authorized to access that location.'));
}
return $next($request);
}
In Kernel.php
'admin' => \App\Http\Middleware\AdminMiddleware::class,
Route::group(['middleware' => 'admin'], function(){
// All admin Routes
});
You Can also Use Spatie package for this.
https://spatie.be/docs/laravel-permission/v5/basic-usage/middleware
Just Check If Role is allowed to use that route:
Route::group(['middleware' => ['auth', 'role:admin']], function () {
// All routes available for admin
});
I have the following middleware in my PostController.
public function __construct()
{
$this->middleware('auth')->except(['index', 'show']);
}
I understand any authenticated user can still edit a post by visiting localhost/posts/{post}/edit so I've protected that by the following code.
public function edit(Post $post)
{
if(auth()->user()->id === $post->user_id){
$categories = Category::all();
return view('edit-post', compact(['post', 'categories']));
} else{
abort(403, 'Unauthorized.');
}
}
Now, I'm wondering is it necessary to protect the destroy method? Is it possible for an authenticated user to delete a post they didn't create in this case? If they can could I kindly know how they can?
My destroy method
public function destroy(Post $post)
{
Storage::disk('public')->delete($post->imagePath);
$post->delete();
return redirect(route('posts.index'))->with('flash', 'Post Deleted Successfully');
}
one easy way to protect all your methods that need authentification is to use relations.
You are sending a post id in the URL by use model injection to preload $post from DB. Avoid that and use the id of the post yourself
public function destroy($postId)
{
$post = auth()->user()->posts()->findOrFail($postId);
Storage::disk('public')->delete($post->imagePath);
$post->delete();
return redirect(route('posts.index'))->with('flash', 'Post Deleted Successfully');
}
The route will return a 404 if the post id is not one of the user owned posts.
Same for the edit
public function edit($postId)
{
$post = auth()->user()->posts()->findOrFail($postId);
$categories = Category::all();
return view('edit-post', compact(['post', 'categories']));
}
As for the change in response code 404 instead of a 403, it is on purpose, since the user is authenticated and you dont want any user to know if another post with random ID that is not his exists or not hence 404. like if he put a non existing post id to delete or edit.
First, you should be read about Laravel policy, which will make your code more clear.
For destroy method,
I will give you an example, you can try it BTW
post_table
id
user_id
title
1
40
Post1
2
50
Post2
If the user id: 40 tries to delete the post witch id is id: 1 there is no problem,
BUT let's say the user knows about the web app and just changes the id in the URL localhost/posts/2/delete, He/She will delete any post without policy.
I need to pass an id to the route (web.php) from the form. My application has comment section at opporunities/id (id in value) , Whenever non-Auth user submits comment , my app will ask login and redirects to /opportunities but i need /opportunities/id. In the form of comment i have submitted page id. I have setup my route as
Route::post('/opportunities', 'OpportunitiesController#postPost')->name('posts.post'); Now if i can pass that id to as /opportunities/id then after login user will automatically lands on that page. I have manually tested and attached id and it works. Do I need to use "use Illuminate\Http\Request;" to get form data to web.php (route)? to get request post id? All i need is to add id after Route:post('/opportunites/'). Any suggestion and help will be appropriated.
What I did was and figured out is that
action="{{route('opportunities',['returnvalue'=> $post['id']]) }}" I still got error #bipin answer but i passed it with as parameter and solved. Thanks bipin for suggestion though!
One solution could be, pass your post id inside the form
View Blade
{{ Form::hidden('post_id', 'value', array('id' => 'post_id')) }}
Controler
use Illuminate\Http\Request;
public function comment(Request $request)
{
//Validation
$this->validate($request, [
'post_id' => 'required'
]);
//Inside variable
$input = $request->all();
// OR
$request->post_id;
}
Top of my controller i have added:
use Auth;
function in my controller
public function details($id)
{
if(Auth::check())
{
$user = Auth::user();
$product = Product::find($id);
$cart->product_id = $product->id;
$cart->category_id = $product->category_id;
$cart->user_id = $user->id;
dd($cart->user_id); //check if its storing the value
}
else {
return redirect()->route('login');
}
}
when I run this i get error:
Creating default object from empty value
If I remove the $user->id line the error goes.
I tried adding constructor also but still got same error
public function __construct() {
$this->middleware('auth');
}
dd is showing other details after it checks if user is logged in.
Is there a way to get user id of logged in user from users table that is created by default.
Thanks!
The issue is you’re calling $cart->product_id, but the $cart variable isn’t defined as far as I can see. PHP doesn’t know what to do, so because you try and assign a property to it, PHP assumes you want $cart to be a class, hence the “Creating default object from empty value” message.
Other than that, you code could be improved by using middleware to authenticate your users, and relations on your Eloquent models so you’re not manually assigning relation IDs.
Try like this,
You forgot to initials cart object
$cart = new Cart;
$cart->product_id = $product->id;
$cart->category_id = $product->category_id;
$cart->user_id = $user->id;
dd($cart->user_id); //check if its storing the value
I am using Laravel 5.2 and Blade templating, currently I am using this code to send the user to their own profile
href="{{ route('profile.index', ['username' => Auth::user()->username]) }}
This code is in an #if statement in blade, I was wondering how I would be able to check to make sure the user is on their own profile before I show them elements they should only be able to see on their own profile?
Just use check similar to this in your controller:
if (Auth::check()) // Checks if user authenticated
{
$userId = Auth::user()->id; // Gets user ID
// Do some stuff
}
return view('profile', compact('profileInfo'));
In this case any user will see only he's own profile.