我正在尝试设置帖子管理部分。该部分的任务是显示属于登录用户的所有文章。我对标签和类别所做的方式工作正常(不需要为任何用户过滤标签和类别)。帖子页面可以正确显示登录用户拥有的帖子,但问题是用户无法编辑或显示任何帖子,并且尝试存储新帖子会重定向到 403 页面。我对这个错误感到困惑,并且没有任何解决方案。我感谢一些帮助。
后模特
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = [
'user_id', 'category_id', 'name', 'slug', 'excerpt', 'body', 'status', 'file'
];
public function category()
{
return $this->belongsTo(Category::class);
}
public function user()
{
return $this->belongsTo(User::class);
}
public function tags()
{
return $this->belongsToMany(Tag::class);
}
}
后控制器
<?php
namespace App\Http\Controllers\Admin;
use App\Models\Post;
use App\Models\Category;
use App\Models\Tag;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\PostStoreRequest;
use App\Http\Requests\PostUpdateRequest;
use Illuminate\Support\Facades\Storage;
class PostController extends Controller
{
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
$posts = Post::orderBy('id', 'DESC')
->where('user_id', auth()->user()->id)
->paginate();
return view('admin.posts.index', compact('posts'));
}
public function create()
{
$categories = Category::orderBy('name', 'ASC')->pluck('name', 'id');
$tags = Tag::orderBy('name', 'ASC')->get();
return view('admin.posts.create', compact('categories', 'tags'));
}
public function store(PostStoreRequest $request)
{
$post = Post::create($request->all());
$this->authorize('pass', $post);
//IMAGE
if($request->file('image')){
$path = Storage::disk('public')->put('image', $request->file('image'));
$post->fill(['file' => asset($path)])->save();
}
//TAGS
$post->tags()->attach($request->get('tags'));
return redirect()->route('posts.edit', $post->id)->with('info', 'Success');
}
public function show($id)
{
$post = Post::find($id);
$this->authorize('pass', $post);
return view('admin.posts.show', compact('post'));
}
public function edit($id)
{
$categories = Category::orderBy('name', 'ASC')->pluck('name', 'id');
$tags = Tag::orderBy('name', 'ASC')->get();
$post = Post::find($id);
$this->authorize('pass', $post);
return view('admin.posts.edit', compact('post', 'categories', 'tags'));
}
public function update(PostUpdateRequest $request, $id)
{
$post = Post::find($id);
$this->authorize('pass', $post);
$post->fill($request->all())->save();
//IMAGE
if($request->file('image')){
$path = Storage::disk('public')->put('image', $request->file('image'));
$post->fill(['file' => asset($path)])->save();
}
//TAGS
$post->tags()->sync($request->get('tags'));
return redirect()->route('posts.edit', $post->id)->with('info', 'Success');
}
public function destroy($id)
{
$post = Post::find($id)->delete();
$this->authorize('pass', $post);
return back()->with('info', 'Deleted');
}
}
更新后请求
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class PostUpdateRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
$rules = [
'name' => 'required',
'slug' => 'required|unique:posts,slug,' . $this->post,
'user_id' => 'required|integer',
'category_id' => 'required|integer',
'tags' => 'required|array',
'body' => 'required',
'status' => 'required|in:DRAFT,PUBLISHED',
];
if($this->get('image'))
$rules = array_merge($rules, ['image' => 'mimes:jpg,jpeg,png']);
return $rules;
}
}
PostStore请求
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class PostStoreRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
$rules = [
'name' => 'required',
'slug' => 'required|unique:posts,slug',
'user_id' => 'required|integer',
'category_id' => 'required|integer',
'tags' => 'required|array',
'body' => 'required',
'status' => 'required|in:DRAFT,PUBLISHED',
];
if($this->get('image'))
$rules = array_merge($rules, ['image' => 'mimes:jpg,jpeg,png']);
return $rules;
}
}
例如,post.edit
@extends('admin.admin')
@section('content')
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="card">
<div class="card-header">
{{ __('Editar artículo') }}
</div>
<div class="card-body">
{!! Form::model($post, ['route' => ['posts.update', $post->id], 'method' => 'PUT']) !!}
@include('admin.posts.partials.form')
{!! Form::close() !!}
</div>
</div>
</div>
</div>
</div>
@endsection
最后是表格
<div class="form-group">
{{ Form::hidden('user_id', auth()->user()->id) }}
</div>
<div class="form-group">
{{ Form::label('category_id', 'Category') }}
{{ Form::select('category_id', $categories, null, ['class' => 'form-control']) }}
</div>
<div class="form-group">
{{ Form::label('name', 'Tag name') }}
{{ Form::text('name', null, ['class' => 'form-control', 'id' => 'name']) }}
</div>
<div class="form-group">
{{ Form::label('slug', 'URL friendly') }}
{{ Form::text('slug', null, ['class' => 'form-control', 'id' => 'slug']) }}
</div>
<div class="form-group">
{{ Form::label('image', 'Image') }}
{{ Form::file('image') }}
</div>
<div class="form-group">
{{ Form::label('slug', 'State') }}
<label>
{{ Form::radio('status', 'PUBLISHED') }} Published
</label>
<label>
{{ Form::radio('status', 'DRAFT') }} Draft
</label>
</div>
<div class="form-group">
{{ Form::label('tags', 'Tags') }}
<div>
@foreach($tags as $tag)
<label>
{{ Form::checkbox('tags[]', $tag->id) }} {{ $tag->name }}
</label>
@endforeach
</div>
</div>
<div class="form-group">
{{ Form::label('excerpt', 'Excerpt') }}
{{ Form::textarea('excerpt', null, ['class' => 'form-control', 'rows' => '2']) }}
</div>
<div class="form-group">
{{ Form::label('body', 'Description') }}
{{ Form::textarea('body', null, ['class' => 'form-control']) }}
</div>
<div class="form-group">
{{ Form::submit('Guardar', ['class' => 'btn btn-sm btn-primary']) }}
</div>
@section('scripts')
<script src="{{ asset('components/stringToSlug/jquery.stringToSlug.min.js') }}"></script>
<script>
$(document).ready(function(){
$("#name, #slug").stringToSlug({
callback: function(text){
$('#slug').val(text);
}
});
});
</script>
@endsection
抱歉延期,但有必要解释一下问题。
控制器方法中的authorize()方法寻找相应的策略。如果 Laravel 找不到相应的策略,它会抛出未经验证的异常。
所以在这种情况下
$this->authorize('pass', $post)
,期望找到一个PostPolicy
类,否则会抛出未经授权的异常,该异常会被中间件转换为403重定向。
了解有关政策的更多信息 https://laravel.com/docs/8.x/authorization#creating-policies。
注意:使用FormRequest处理验证时,可以在FormRequest中进行授权,不需要在控制器方法中重复授权