Using Policies in Laravel 5.5.14 - api

I am new in using policies in Laravel. I am learning API Development using Laravel. My codes are as bellows.
TopicPolicy.php
<?php
namespace App\Policies;
use App\User;
use App\Topic;
use Illuminate\Auth\Access\HandlesAuthorization;
class Topicpolicy
{
use HandlesAuthorization;
public function update(User $user, Topic $topic)
{
return $user->ownsTopic($topic);
}
public function destroy(User $user, Topic $topic)
{
return $user->ownsTopic($topic);
}
}
AuthServiceProvider.php
<?php
namespace App\Providers;
use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
}
TopicController.php
<?php
namespace App\Http\Controllers;
use App\Topic;
use App\Post;
use Illuminate\Http\Request;
use App\Http\Requests\StoreTopicRequest;
use App\Transformers\TopicTransformer;
use League\Fractal\Pagination\IlluminatePaginatorAdapter;
class TopicController extends Controller
{
public function destroy(Topic $topic) {
$this->authorize('destroy',$topic);
$topic->delete();
return response(null,204);
}
}
I am getting error This action is unauthorized.. I don't know how to use policies. Could anyone guide me to use policies in Laravel 5.5.14 ?

In the AuthServiceProvider class you have to register the policy in the policies aray. Laravel documents is a good place to start
protected $policies = [
\App\Topic::class => \App\Policies\Topicpolicy::class
]
Second obtain a personal token from your app so you can use it to make calls to your api. You use passport and passport comes with ready to use Vue components to help you start.If you want to consume the api inside the same application check here.
I am not sure what you try to accomplice with the HandlesAuthorization trait inside the policy. Laravel has a middleware for this reason for us to use.

Related

Why this coding does not load admin dashboard? problem with middleware or auth? Laravel 8

Why this coding does not load admin dashboard? problem with middleware or auth? Laravel 8
This is the coding. All the files I modified in this regards are as follows. Please help me
This is the AdminController
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Auth;
use Illuminate\Support\Facades\Session;
//use session;
class AdminController extends Controller
{
public function dashboard(){
return view('admin.admin_dashboard');
}
public function login(Request $request){
if($request->isMethod('post')){
$data =$request->all();
//echo "<pre>"; print_r($data); die;
if(Auth::guard('admin')->attempt(['email'=>$data['email'],'password'=>$data['password']])){
return redirect('admin/dashboard');
}else{ session::flash('error_message','Invalid email or password');
redirect()->back();
}
}
return view('admin.admin_login');
}
}
This is the Admin model. It is checked No error in the model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
use HasFactory, Notifiable;
protected $guard='admin';
protected $fillable=[
'name','email','password',
];
protected $hidden=[
'password','rememberToken',
];
}
This is the Middleware file. I think the error may be in this area. Because it works outside the middleware for 2nd auth.
<?php
namespace App\Http\Middleware;
use Auth;
use Closure;
use Illuminate\Http\Request;
class Admin
{
public function handle(Request $request, Closure $next)
{
if(!Auth::guard('admin')->check()){
return redirect('/admin');
}
return $next($request);
}
}
Finally this is admin dashboard rout is not executing

Multi Tenant Razor Page

Looking for an easy way build multi tenant razor page. Looking for the url pattern to be like \{Tenant}\{Page} for all pages in an area. Its fairly easy to add a route param at the end via RazorPagesOptions Conventions. How do you add the param at the beginning?
You can use the IPageRouteModelConvention interface to prefix each route with a route parameter representing the tenant. Create a class that implements the interface, and then override the Apply method, something like the following (untested):
public class CustomPageRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
foreach (var selector in model.Selectors.ToList())
{
selector.AttributeRouteModel.Template = "{tenant}/" + selector.AttributeRouteModel.Template ;
}
}
}
Then register your implementation in ConfigureServices:
services.AddMvc().AddRazorPagesOptions(options =>
{
options.Conventions.Add(new CustomPageRouteModelConvention());
})

Laravel controller based api routing

My normal web app runs w/o any issue. Then I wanted to experiment with APIs. I enabled Passport since I need api authorization (but at this moment, I rather want to get this thing working and I have no idea whether it is a problem with Passport) and I wanted to get simple json output of specific Product. So far, I was not able to get it working. I'll describe contents of each file and if someone can direct me to find the issue in my code, that would be great.
Resources\Product.php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class Product extends JsonResource
{
public function toArray($request)
{
return parent::toArray($request);
}
}
Providers\AuthServiceProviders.php
public function boot()
{
$this->registerPolicies();
Passport::routes();
}
User.php
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
...
}
ProductController.php
class ProductController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function apiShow(Product $product)
{
return new ProductResource($product);
}
...
}
routes/api.php
Route::get('/products/{product}', 'ProductController#apiShow');
Now if I go to http://localhost/public/products/1, it displays the page as expected. But if I type in http://localhost/public/api/products/1, it will always go to home page which is set to localhost/public in HomeController.
If I modify routes/api.php as:
Route::get('/products/{id}', function($id) {
return Product::find($id);
});
I get the correct json output in the browser.

Symfony 3.3.10 routes

I have problem when i try to use routes. It can't be generated, i tried via /app/config/routes.xml but when i modify i get error that the file is not YAML format.
The controller looks:
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
class MainController extends Controller
{
public function indexAction(Request $request)
{
return $this->render('main/index.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.project_dir')).DIRECTORY_SEPARATOR,
]);
}
}
When i try to visit /index or main/index it gives me route not found!
:#
Nor works when i put use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; first before Controller.
First, you have to put namespace on header.
Second in Symfony 3.3.10 which route you want to use have to declare before on public function indexAction.
So, your route declaration would be as follows:
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
class MainController extends Controller
{
/**
*#Route("visit/index")
*/
public function indexAction(Request $request)
{
return $this->render('main/index.html.twig', ['base_dir' => realpath($this->getParameter('kernel.project_dir')).DIRECTORY_SEPARATOR,]);
}
}

How to Create MY_Controller in Yii2

I'm newbie in Yii, especially Yii2. How can I create MY_Controller like CI in YII2 ? so other controllers will extend to MY_Controller.
in YII2, called as BaseController. I think in another framework have same name BaseController .
First, if you're using basic template, create BaseController.php inside component directory.
namespace app\components;
use Yii;
use yii\web\Controller;
use yii\helpers\Url;
class BaseController extends Controller
{
public function init()
{
parent::init();
}
public function _anotherMethod(){ /* your code goes here */ }
}
Next in your other controllers :
namespace app\controllers;
use Yii;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\helpers\Url;
use app\components\BaseController;
class YourController extends BaseController
{
public function init()
{
parent::init();
}
public function _anotherAction()
{
// your code
}
}
I hope it will help you