I want to show some user data by id. Simple.
user/{id} -> get data from a Controller's method.
I have this:
Route::group(['prefix' => 'user/{id}', 'where' => ['id' => '[0-9]+']], function() {
Route::get('delete', 'UserController#delete')->name('admin.access.user.delete-permanently');
Route::get('restore', 'UserController#restore')->name('admin.access.user.restore');
Route::get('mark/{status}', 'UserController#mark')->name('admin.access.user.mark')->where(['status' => '[0,1]']);
Route::get('password/change', 'UserController#changePassword')->name('admin.access.user.change-password');
Route::post('password/change', 'UserController#updatePassword')->name('admin.access.user.change-password');
});
How can I access a method as a default for user/{id}?
You can do this in your controller
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Show the profile for the given user.
*
* #param int $id
* #return Response
*/
public function show($id)
{
//Fetch and send the user to the "profile" blade file in the folder "resources/views/user"
return view('user.profile', ['user' => User::findOrFail($id)]);
}
public function changePassword($id)
{
$user = User::findOrFail($id);
return $user->update(
'password' => bcrypt(123456)
);
}
}
Related
I'm making a website project using Laravel Jetstream with stack inertia. In this project, I added the package spatie/laravel-permission. When I try to authorize the controller to protect against malicious users from accessing the URL directly I create a trait that I can call for any controller I want and here is the code
trait Authorizable
{
private $abilities = [
'index' => 'view',
'edit' => 'edit',
'show' => 'view',
'update' => 'edit',
'create' => 'add',
'store' => 'add',
'destroy' => 'delete',
];
/**
* Override of callAction to perform the authorization before
*
* #param $method
* #param $parameters
* #return mixed
*/
public function callAction($method, $parameters)
{
if ($ability = $this->getAbility($method)) {
$this->authorize($ability);
}
return parent::callAction($method, $parameters);
}
public function getAbility($method)
{
$routeName = explode('.', \Request::route()->getName());
$action = Arr::get($this->getAbilities(), $method);
return $action ? $action . '_' . $routeName[0] : null;
}
private function getAbilities()
{
return $this->abilities;
}
public function setAbilities($abilities)
{
$this->abilities = $abilities;
}
}
after that, I call the trait on the controller
use App\Http\Controllers\Controller;
use App\Traits\Authorizable;
use Illuminate\Http\Request;
use Inertia\Inertia;
class UsersController extends Controller
{
use Authorizable;
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return Inertia::render('Admin/Users/Index');
}
this is my route
Route::middleware(['auth:sanctum', config('jetstream.auth_session'), 'verified',])->group(function () {
Route::middleware(['role:Admin'])->prefix('admin')->group(function () {
Route::resource('users', AdminUsers::class, ['as' => 'admin']);
});
});
but unfortunately, after I try to access the URL /admin/users, I get a message 403: THIS ACTION IS UNAUTHORIZED.
I have no idea to solve this problem, could anyone here to help me to solve this problem or give me some advice? it will save me.
Thank You
I'm new to Laravel, so here I want to make a view for login and register, and then I change the default view login and register into my own view, I changed it in the route and then it work, and then I try to run this code: php artisan ui:auth and then my login view before, it changes to the default view of Laravel. How to change it again into my login and view design ? Thank you.
This is my route 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!
|
*/
Route::get('/', function () {
return view('pages/home');
});
Route::get('/register','Auth\AuthController#register');
Route::post('/register','Auth\AuthController#postRegister')->name('register');
Route::get('/login','AuthController#login');
Route::post('/login','AuthController#postLogin')->name('login');
and this is my AuthController
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Laravel\Socialite\Facades\Socialite;
class AuthController extends Controller
{
public function register()
{
return view('login_register/register');
}
public function postRegister(Request $request )
{
User::create([
'name'=> $request->nama,
'email'=> $request->email,
'password'=> bcrypt($request->password)
]);
return redirect('/login');
}
public function login()
{
return view('login_register/login');
}
public function postLogin(Request $request)
{
if(!\Auth::attempt(['email' => $request->email, 'password' => $request->password ])){
return redirect()->back();
}
return redirect('/galangdana/list');
}
public function redirectToProvider($provider)
{
return Socialite::driver($provider)->redirect();
}
/**
* Obtain the user information from provider. Check if the user already exists in our
* database by looking up their provider_id in the database.
* If the user exists, log them in. Otherwise, create a new user then log them in. After that
* redirect them to the authenticated users homepage.
*
* #return Response
*/
public function handleProviderCallback($provider)
{
$user = Socialite::driver($provider)->user();
$authUser = $this->findOrCreateUser($user, $provider);
Auth::login($authUser, true);
return redirect('/');
}
/**
* If a user has registered before using social auth, return the user
* else, create a new user object.
* #param $user Socialite user object
* #param $provider Social auth provider
* #return User
*/
public function findOrCreateUser($user, $provider)
{
$authUser = User::where('provider_id', $user->id)->first();
if ($authUser) {
return $authUser;
}
else{
$data = User::create([
'name' => $user->name,
'email' => !empty($user->email)? $user->email : '' ,
'provider' => $provider,
'provider_id' => $user->id
]);
return $data;
}
}
}
?>
You can override the showLoginForm() method, in you LoginController.php:
public function showLoginForm()
{
return view('my.view');
}
It overrides the function showLoginForm defined in the trait Illuminate\Foundation\Auth\AuthenticatesUsers.
For registration, you showRegistrationForm method, defined in Illuminate\Foundation\Auth\RegistersUsers trait:
public function showRegistrationForm()
{
return view('my.register.view');
}
Hope it helps.
solved, that becasue i put Auth::routes() so that make multiple login, thank you for the answer 🙏
I am working on Laravel passport api in which i am using spatie package for user role's and permission's. I have to perform certain operation ('store','view','update','delete') based on user permission's.
For this purpose i have created a trait and used in controller but it is not working correctly.
On every api request it throw's an exception "This action is unauthorized" either the user has permission or not.
Authorize Trait :
<?php
namespace App;
/*
* A trait to handle authorization based on users permissions for given controller
*/
trait Authorizable
{
/**
* Abilities
*
* #var array
*/
private $abilities = [
'index' => 'view',
'edit' => 'edit',
'show' => 'view',
'update' => 'edit',
'create' => 'add',
'store' => 'add',
'destroy' => 'delete'
];
/**
* Override of callAction to perform the authorization before it calls the action
*
* #param $method
* #param $parameters
* #return mixed
*/
public function callAction($method, $parameters)
{
if( $ability = $this->getAbility($method) ) {
$this->authorize($ability);
}
return parent::callAction($method, $parameters);
}
/**
* Get ability
*
* #param $method
* #return null|string
*/
public function getAbility($method)
{
$routeName = explode('.', \Request::route()->getName());
$action = array_get($this->getAbilities(), $method);
return $action ? $action . '_' . $routeName[0] : null;
}
/**
* #return array
*/
private function getAbilities()
{
return $this->abilities;
}
/**
* #param array $abilities
*/
public function setAbilities($abilities)
{
$this->abilities = $abilities;
}
}
Routes:
Route::middleware('auth:api')->group(function () {
Route::post('user', 'ApiController#user');
Route::post('view_department', 'DepartmentController#index');
Route::post('add_department', 'DepartmentController#store');
Route::post('edit_department', 'DepartmentController#update');
Route::post('delete_department', 'DepartmentController#destroy');
Route::post('/logout', 'ApiController#logout');
}); // auth middleware ends
Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use App\User;
use App\Authorizable;
use Illuminate\Support\Facades\Validator;
use App\Department;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
class DepartmentController extends Controller
{
use Authorizable;
//
public function index(Request $request) {
// return response
return response()->json([
'success' => 'You have the permission to view departments!']);
}
//
public function store(Request $request) {
// validate the posted data
$validator = Validator::make($request->all(), [
'name' => 'required|string|unique:departments',
]);
// return errors
if ($validator->fails())
{
return response(['errors'=>$validator->errors()->all()]);
}
$department = new Department;
$department->name = $request->name;
$department->save();
// return response
return response()->json([
'success' => 'Successfully created department!']);
}
}
I am badly stack at it, don't know where i am going wrong. I would highly appreciate if anyone guide me through this.
Thanks,
I'm trying "laravel-modules" and "Laravel-permission package". But when run post, it has issue 'Method [validate] does not exist.'. i have added 'use Validator;' but no thing change. In some topics, i remove "use Illuminate\Routing\Controller;" in PermissionController, but it have error
Controller
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
My PermissionController
namespace Modules\User\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Auth;
//Importing laravel-permission models
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use Session;
class PermissionController extends Controller
{
// use Validator;
public function __construct() {
$this->middleware(['auth', 'isAdmin']); //isAdmin middleware lets only users with a //specific permission permission to access these resources
}
/**
* Display a listing of the resource.
* #return Response
*/
public function index()
{
$permissions = Permission::all(); //Get all permissions
return view('user::permissions/index')->with('permissions', $permissions);
// return view('user::index');
}
/**
* Show the form for creating a new resource.
* #return Response
*/
public function create()
{
$roles = Role::get(); //Get all roles
return view('user::permissions/create')->with('roles', $roles);
}
/**
* Store a newly created resource in storage.
* #param Request $request
* #return Response
*/
public function store(Request $request)
{
$this->validate($request, [
'name'=>'required|max:40',
]);
$name = $request['name'];
$permission = new Permission();
$permission->name = $name;
$roles = $request['roles'];
$permission->save();
if (!empty($request['roles'])) { //If one or more role is selected
foreach ($roles as $role) {
$r = Role::where('id', '=', $role)->firstOrFail(); //Match input role to db record
$permission = Permission::where('name', '=', $name)->first(); //Match input //permission to db record
$r->givePermissionTo($permission);
}
}
return redirect()->route('permissions.index')
->with('flash_message',
'Permission'. $permission->name.' added!');
}
}
Route
Route::group(['middleware' => 'web', 'prefix' => 'permissions', 'namespace' => 'Modules\User\Http\Controllers'], function()
{
Route::get('/', 'PermissionController#index');
Route::get('/create', 'PermissionController#create');
Route::post('/', 'PermissionController#store');
Route::delete('/', ["as" => "permissions.destroy", "uses" => "PermissionController#destroy"]);
});
Add back in use Validator in your PermissionController. Add this right after use Auth;. You have currently added this in the wrong place.
Then change your $this->validate(...) code to:
// validate the input
$validation = Validator::make( $request->all(), [
'name'=>'required|max:40',
]);
// redirect on validation error
if ( $validation->fails() ) {
// change below as required
return \Redirect::back()->withInput()->withErrors( $validation->messages() );
}
I was trying
$this->validate($request, [
'password' => 'required|confirmed|min:6',
]);
But in Laravel 5.7 following code did the trick for me
$request->validate([
'password' => 'required|confirmed|min:6',
]);
I am using hashid to hash the id parameters in url. I have it set up in my model to automatically hash the id. This is working fine. My problem is decoding the hash in a middleware returns null. I'm not sure if this is a problem with my middleware or because of the hashing.
Model:
public function getIdAttribute($value)
{
$hashids = new \Hashids\Hashids(env('APP_KEY'),10);
return $hashids->encode($value);
}
Middleware:
<?php
namespace App\Http\Middleware;
use Closure;
class HashIdsDecode
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
dd($request->id); //Returns null on show method - example localhost:8000/invoices/afewRfshTl
if($request->has('id'))
{
$hashids = new \Hashids\Hashids(env('APP_KEY'),10);
dd($hashids->decode($request->input('id')));
}
return $next($request);
}
}
Route:
Route::resource('invoices','InvoiceController');
Controller:
public function show($id)
{
$invoice = Invoice::find($id);
return view('invoices.show', [
'invoice' => $invoice,
'page_title' => ' Invoices',
'page_description' => 'View Invoice',
]);
}
NOTE: if I bypass the middleware and do it directly in my controller like this it works but it requires me to repeat myself over and over and probably not the best way to do it.
public function show($id)
{
$hashids = new \Hashids\Hashids(env('APP_KEY'),10);
$invoiceId = $hashids->decode($id)[0];
$invoice = Invoice::find($invoiceId);
return view('invoices.show', [
'invoice' => $invoice,
'page_title' => ' Invoices',
'page_description' => 'View Invoice',
]);
}
Personally, I would be more inclined to write a model trait. You can then use the trait on only the models required, rather than assuming every ID argument in a request is a Hash ID.
E.g.
namespace App\Models\Traits;
use Hashids\Hashids;
use Illuminate\Database\Eloquent\Builder;
trait HashedId
{
public function scopeHashId(Builder $query, $id)
{
$hashIds = new Hashids(env('APP_KEY'), 10);
$id = $hashIds->decode($id)[0];
return $query->where('id', $id);
}
}
Then to use it, you'd use the trait on your Invoice model (edit):
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Invoice extends Model
{
use \App\Models\Traits\HashedId;
// ...
}
And execute the following query in your controller:
public function show($id)
{
$invoice = Invoice::hashId($id)->firstOrFail();
return view('invoices.show', [
'invoice' => $invoice,
'page_title' => ' Invoices',
'page_description' => 'View Invoice',
]);
}