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.
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 registration auth in laravel project and i need some existing datas should show up on the registration form , please guide me up..
http://165.232.187.63/register
This is my register page and i need to fetch existing database values in the registration form. for example
<select>
#foreach($users as $items)
<option>{{ $items->id }}</option>
#endforeach
</select>
How to customize this...
I have tried adding in web.php file
Route::get('/register','App\Http\Controllers\Auth\UserController#index');
And in my UserController.php
public function index()
{
$users = User::all();
return view('auth.register')
->with('users', $users);
}
But can't use both post and get for register auth
You need to use separate endpoints for this task
one to load the view
Route::get('/register','App\Http\Controllers\Auth\UserController#index');
and the other to do the actual registration
Route::post('/register','App\Http\Controllers\Auth\UserController#register');
of course in the UserController, you will have a register method that handles the actual registration process
I want only user with same name with the url id can access using if condition
Example
User logged on with name jer
He should only access url with /User-Profile/jer
And not access other page /User-Profile/abc that are not equal to his
name
Doing something like Example:
if{id}!=={{auth->name}}
{
Route::get('NoPermission', 'Restriction#index');
}
else
{
Route::get('/User-Profile/{name}/', 'AccountController#index');
}
How can I compare {name} from url to {auth->name} ?
Route
Route::get('/User-Profile/{name}/', 'AccountController#index');
Blade
<a href="/dashboard/User-Profile/{{ Auth::user()->name }}">{{ Auth::user()->name
}}</a>
You can't access Auth like that in your routes, compare it in your AccountController instead:
public function index($name){
if($name != Auth::user->name()) abort(403);
else...
}
In a service provider (Doesn't really matter which one, but it would be clearer if done in the RouteServiceProvider), add a route binding in the boot method as documented in https://laravel.com/docs/6.x/routing#explicit-binding
public function boot()
{
// Declare binding 'name'.
Route::bind('name', function ($name) {
return App\User::where('name', $name)->first() ?? abort(404);
});
}
Then, use that binding in your routes file
// Use binding name and middleware auth to make sure this route can't be accessed by guest users.
Route::get('/User-Profile/{name}/', 'AccountController#index')->middleware('auth')->name('account_profile');
In your blade file, you can do the following
{{-- Make sure the link is only visible for authenticated users https://laravel.com/docs/6.x/blade#if-statements --}}
#auth
<a href="{{ route('account_profile', ['name' => auth()->user()->name]) }}</a>
#endauth
Allow acces to the page , but before showing content ,check if the url path is == to the id name .
Actually, you can check in your routes like this:
Route::get('/profile/{name}', function(String $name) {
if (!Auth::check() || $name !== Auth::user()->name) {
abort(404);
}
return view("view.auth.profile", ['profile => App\Profile::where('user_id', '=', Auth::id())->first()]);
});
However if you use
Route::get('/profile', 'AuthController#profile')->middleware('auth');
and use Auth::user() in your controller to select the correct profile.
The benefit here is that any unauthenticated users will be automatically redirected to your login page, and there's no need to include the name on your profile link.
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();
}
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;
}