Laravel - 403 redirect. Redirect is correct working for tags and category sections but not for users - laravel

I'm trying to set the post admin section. The mission for that section is to show all articles that belong to logged user. The way I'm doing for tags and categories is working correct (tags and categories doesn't need to be filtered for any user). The post page works correctly show the owned post for logged user, but the problem is that the user can't edit or show any post and trying to store a new post redirects to 403 page. I'm confuse by the error and I don't have any solution. I appreciate some help.
PostModel
<?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);
}
}
PostController
<?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');
}
}
PostUpdateRequest
<?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;
}
}
PostStoreRequest
<?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;
}
}
And for example, the 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
And finally the form
<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
Sorry for the extension but it was necessary to explain the problem.

The authorize() method in controller method looks for a corresponding policy. If Laravel can't find the corresponding policy it throws unauthenticated exception.
So in this case $this->authorize('pass', $post), expects to find a PostPolicy class, otherwise it will throw unauthorized exception which is converted to 403 redirect by middleware.
Read more about Policies https://laravel.com/docs/8.x/authorization#creating-policies.
Note: When using FormRequest to handle validation, authorization can be done in FormRequest and there's not need to duplicate authorization in controller method

Related

how to post laravel using Vue.js

I'm trying to figure out how to use vue.js, I want to still store the date in a MySQL database when a post has been submitted, as well having the post show instantly like ajax(without the page refreshing).
Here is my code thus far, here is a rough sketch, I'm still trying to wrap my head around so please bear with me
dashboard.blade.php
#extends('layouts.layout')
#section('title')
Dashboard
#endsection
#section('content')
<div class="dashboard eli-main">
<div class="container ">
<div class="row">
<div class="col-md-6 col-md-12">
<h1>{{$user->username}}</h1>
<h4>What do you have to say?</h4>
<form action="{{ route('post.create') }}" method="post">
<div class="form-group">
<textarea class="form-control" name="body" id="body" rows="5" placeholder="Your Post"></textarea>
</div>
<button type="submit" class="mybtn2">Create Post</button>
<input type="hidden" value="{{ Session::token() }}" name="_token">
</form>
#foreach($posts as $post)
<article class="post">
<h4>{{ $post->user->username }}</h4>
<p class="post-bod">
{{ $post->body }}
</p>
<div class="info">
made on {{ date('F d, Y', strtotime($post->created_at)) }}
</div>
</article>
#endforeach
</div>
</div>
</div>
</div>
<script>
var app = new Vue({
el: 'post-bod',
data: {
post: body
}
})
</script>
#endsection
PostController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Post;
use App\User;
use Illuminate\Support\Facades\Auth;
use App\Http\Requests;
class PostController extends Controller
{
public function getDashboard()
{
$posts = Post::orderBy('created_at', 'desc')->get();
$cookie = cookie('saw-dashboard', true, 15);
$users = User::all();
$user = new User();
//return view('dashboard', array('user'=> Auth::user()), compact('users'))->withCookie($cookie);
return view('dashboard',array('user'=> Auth::user(), 'posts' => $posts, compact('users')))->withCookie($cookie);
}
public function postCreatePost(Request $request)
{
$this->validate($request,[
'body' => 'required|max:1000'
]);
$post = new Post();
$post->body = $request['body'];
$message = 'There was an error';
if($request->user()->posts()->save($post)){
$message = 'Post Successfully Created';
}
return redirect()->route('dashboard');
}
}
UserController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\User;
use App\Http\Requests;
class UserController extends Controller
{
public function getWelcome()
{
$user = new User();
if (Auth::user()){
return redirect()->route('dashboard');
}
return view('welcome', array('user'=> Auth::user()), compact('users') );
}
public function userSignUp(Request $request)
{
$this->validate($request,[
'email' => 'required|email|unique:users',
'username' => 'required|max:120',
'password' => 'required|min:4'
]);
$email = $request['email'];
$username = $request['username'];
$password = bcrypt($request['password']);
$user = new User();
$user->email = $email;
$user->username = $username;
$user->password = $password;
$user->save();
return redirect()->route('dashboard');
}
public function postSignin(Request $request)
{
$remember = $request->input('remember_me');
if(Auth::attempt(['email'=> $request['email'], 'password' => $request['password']], $remember )){
return redirect()->route('dashboard');
}
return redirect()->back();
}
public function getLogout()
{
Auth::logout();
return redirect()->route('home');
}
}

Laravel 5.2 controller index returns blank page

I created a route to a simple contact page. I use a controller to save the data in the database and display them on the same page. When I submit the form I get a blank page but I want the user to stay on the contact. I tried to pass the index view but then I get errors.
The files are
route.php
Route::get('contact', 'ContactController#index');
Route::post('contact', 'ContactController#create');
ContactController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Contact;
class ContactController extends Controller
{
public function index() {
$contacts = Contact::orderBy('created_at', 'asc')->get();
return view('/contact', [ 'contacts' => $contacts ]);
}
public function create(Request $request) {
$name = $request->input('name');
$contact = new Contact;
$contact->name = $name;
$contact->save();
#return view('/contact');
}
}
Contact.php
<?php
Namespace App;
use Illuminate\Database\Eloquent\Model;
class Contact extends Model
{
protected $fillable = ['name'];
}
?>
contact.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="panel panel-default">
<div class="panel-heading">Contact page</div>
<div class="panel-body">
{!! Form::open(array('url' => 'contact')) !!}
{!! Form::label('name', 'Name') !!}
{!! Form::text('name'); !!}
{!! Form::submit('Submit'); !!}
{!! Form::close() !!}
#if (count($contacts) > 0)
#foreach ($contacts as $contact)
{{ $contact->name }}
#endforeach
#endif
</div>
</div>
</div>
</div>
</div>
#endsection
Try to put contact.blade.php inside views folder and use view('contact', [...]) instead of view('/contact');, you don't need the slash and add return back() to create method:
public function create(Request $request) {
$name = $request->input('name');
$contact = new Contact;
$contact->name = $name;
$contact->save();
return back();
}

Error message not showing in laravel

I'm using Laravel 5.2 and I'm trying to get the error message to show when I attempt to login with the wrong username and password combination, so when I do that I don't get an error message showing. I'm not sure where I'm going wrong.
My controler
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Input;
class HomeController extends Controller
{
public function login(Request $request)
{
if(Auth::attempt(array('name' => Input::get('name'), 'password' => Input::get('password'))))
{
return redirect()->route('dashboard');
}else{
return redirect()->route('home')
->with('message', 'Your username and password combination is wrong')
->withInput();
}
}
}
my index.blade.php
#if ($errors->any())
{{ implode('', $errors->all('<div>:message</div>')) }}
#endif
<div class="form-wrapper">
<div class="login-header">
<h1>Login</h1>
</div>
<div class="form_input">
{{ Form::open(array('url' => 'admin/')) }}
<div class="form_group">
{{ Form::label('name', 'Name') }}
{{ Form::text('name', '' , array("class" => "form-control")) }}
</div>
<div class="form_group password-section">
{{ Form::label('password', 'Password') }}
{{ Form::password('password', array("class" => "form-control")) }}
</div>
<div class="form_group submit_button">
{{ Form::submit('Submit', array("class" =>"btn btn-info submit", "role" => "button")) }}
</div>
{{ Form::close() }}
</div>
</div>
My routes.php
Route::group(['middleware' => 'web'], function()
{
Route::get('admin/', [
'uses' => 'HomeController#index',
'as' => 'home'
]);
Route::post('/signin', [
'uses' => 'HomeController#login',
'as' => 'Login'
]);
});
use Route::group(['middleware' => 'auth'], function() in routes

Laravel 5.2 login issue

Strange issue, when I use the default register route, and I create a user, I can enter inside my app, everything ok. But if I use my CRUD, or the MySQL command for create the user, I can't login.
These credentials do not match our records. (sorry for bad english, I attach the image)
Andrea and Raffaello can login (create with register default route)
Marino can't (generate with my CRUD function) but appear 3 identical records..
routes.php :
Route::group(['middleware' => ['web']], function () {
Route::resource('dash/reports', 'Dash\\ReportsController');
});
/* ruote for Admin */
Route::group(['middleware' => ['role:admin']], function () {
Route::resource('dash/categories', 'Dash\\CategoriesController');
});
Route::group(['middleware' => ['role:admin']], function () {
Route::resource('dash/roles', 'Dash\\RolesController');
});
Route::group(['middleware' => ['role:admin']], function () {
Route::resource('dash/permissions', 'Dash\\PermissionsController');
});
Route::group(['middleware' => ['role:admin']], function () {
Route::resource('dash/users', 'Dash\\UsersController');
});
/* another routes */
Route::auth();
Route::get('/home', 'HomeController#index');
Route::get('/', function () {return view('welcome');});
Controller (custom CRUD operation)
<?php
namespace App\Http\Controllers\Dash;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Auth;
use App\User;
use App\Report;
use App\Category;
use Illuminate\Http\Request;
use Carbon\Carbon;
use Session;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class UsersController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
/**
* Display a listing of the resource.
*
* #return void
*/
public function index()
{
$users = User::paginate(15);
return view('dash.users.index', compact('users'));
}
/**
* Show the form for creating a new resource.
*
* #return void
*/
public function create()
{
return view('dash.users.create');
}
/**
* Store a newly created resource in storage.
*
* #return void
*/
public function store(Request $request)
{
$this->validate($request, ['email' => 'required', 'name' => 'required', 'password' => 'required', 'surname' => 'required', ]);
$user = new User($request->all());
$user->password = bcrypt($request);
$user->save();
return redirect('dash/users');
}
/**
* Display the specified resource.
*
* #param int $id
*
* #return void
*/
public function show($id)
{
$user = User::findOrFail($id);
return view('dash.users.show', compact('user'));
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
*
* #return void
*/
public function edit($id)
{
$user = User::findOrFail($id);
return view('dash.users.edit', compact('user'));
}
/**
* Update the specified resource in storage.
*
* #param int $id
*
* #return void
*/
public function update($id, Request $request)
{
$this->validate($request, ['email' => 'required', 'name' => 'required', 'password' => 'required', 'surname' => 'required', ]);
$user = User::findOrFail($id);
$user->update($request->all());
Session::flash('flash_message', 'User updated!');
return redirect('dash/users');
}
/**
* Remove the specified resource from storage.
*
* #param int $id
*
* #return void
*/
public function destroy($id)
{
User::destroy($id);
Session::flash('flash_message', 'User deleted!');
return redirect('dash/users');
}
}
view:
#extends('layouts.app')
#section('content')
<div class="container">
<h1>Create New User</h1>
<hr/>
{!! Form::open(['url' => '/dash/users', 'class' => 'form-horizontal']) !!}
<div class="form-group {{ $errors->has('email') ? 'has-error' : ''}}">
{!! Form::label('email', trans('users.email'), ['class' => 'col-sm-3 control-label']) !!}
<div class="col-sm-6">
{!! Form::text('email', null, ['class' => 'form-control', 'required' => 'required']) !!}
{!! $errors->first('email', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group {{ $errors->has('name') ? 'has-error' : ''}}">
{!! Form::label('name', trans('users.name'), ['class' => 'col-sm-3 control-label']) !!}
<div class="col-sm-6">
{!! Form::text('name', null, ['class' => 'form-control', 'required' => 'required']) !!}
{!! $errors->first('name', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group {{ $errors->has('password') ? 'has-error' : ''}}">
{!! Form::label('password', trans('users.password'), ['class' => 'col-sm-3 control-label']) !!}
<div class="col-sm-6">
{!! Form::text('password', null, ['class' => 'form-control', 'required' => 'required']) !!}
{!! $errors->first('password', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group {{ $errors->has('surname') ? 'has-error' : ''}}">
{!! Form::label('surname', trans('users.surname'), ['class' => 'col-sm-3 control-label']) !!}
<div class="col-sm-6">
{!! Form::text('surname', null, ['class' => 'form-control', 'required' => 'required']) !!}
{!! $errors->first('surname', '<p class="help-block">:message</p>') !!}
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-3">
{!! Form::submit('Create', ['class' => 'btn btn-primary form-control']) !!}
</div>
</div>
{!! Form::close() !!}
#if ($errors->any())
<ul class="alert alert-danger">
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
#endif
</div>
#endsection
also my custon postLogin() in AuthController for try to overlap default postLogin() - but not working
public function postLogin(LoginRequest $request)
{
if (Auth::attempt(['email' => $request->input('email'), 'password' => $request->input('password')]))
{
return redirect('/dash-board');
}
return redirect('/login')->withErrors([
'email' => 'The credentials you entered did not match our records. Riprovare?',
]);
}
there is it
you need to specify the data you get from $request
you are storing password not correctly
change this :
$user = new User($request->all());
$user->password = bcrypt($request);
$user->save();
to this :
$user = new User($request->all());
$user->password = bcrypt($request->pwInputName);
$user->save();
pwInputName : is the password input name in your view
the issue was that you bcrypt all of $request

I can't store category_id on table

I cannot get category_id when I created a topic. Here are my codes and mysql. I think I have a problem in store method on forum controller.
mysql pro screenshot
Topic create page
#extends('app')
#section('content')
<h1>トピック</h1>
<hr>
{!! Form::open(['url' => 'forums']) !!}
<div class="form-group">
{!! Form::label('title', 'タイトル:') !!}
{!! Form::text('title', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label('body', '本文:') !!}
{!! Form::textarea('body', null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label('category', 'カテゴリー:') !!}
{!! Form::select('category', $categories,null, ['class' => 'form-control']) !!}
</div>
<div class="form-group">
{!! Form::submit('送信',['class' => 'btn btn-primary form-control']) !!}
</div>
{!! Form::close() !!}
#stop
forums controller
<?php
namespace App\Http\Controllers;
use App\Category;
use App\User;
use App\Http\Controllers\Controller;
use App\Http\Requests;
use App\Topic;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class ForumsController extends Controller
{
public function index()
{
$categories = Category::all();
$topics = Topic::latest()->get();
return view('forums.index',compact('categories','topics'));
}
public function create()
{
$categories = Category::lists('title', 'id');
return view('forums.create', compact('categories'));
}
public function store(Request $request)
{
Auth::user()->topics()->save(new Topic($request->all()));
// flash()->success('投稿しました','success');
// return redirect('forums');
}
}
Category model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
protected $fillable = [
'title'
];
public function topics()
{
return $this->hasMany('App\Topic');
}
}
Topic model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class topic extends Model
{
protected $fillable = [
'title',
'body'
];
public function category()
{
return $this->belongsTo('App\category');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
Add category_id to the topic's Model fillable array like this
protected $fillable = [
'title',
'body',
'category_id'
];

Resources