Form submit intercepted by auth middleware in laravel 5 - laravel

I've been working on a laravel 5.7 blog project. I want to comment an article.
I need to achieve this:
Before logging in, I can type anything in comment textarea
I submit comment (of course it would be intercepted by auth middleware)
then I'm redirected to login page
After logging in, I hope my app could submit previous form data (or comment) automatically instead of typing the same comment again
I think that's a very common business logic in many websites nowadays, but how am I supposed to achieve this?
My comments controller here:
public function __construct()
{
$this->middleware('auth');
}
public function store(Post $post) {
$comment = Comment::create([
'body' => session('comment')?:request('body'),
'post_id' => $post->id,
'user_id' => auth()->user()->id
//before logging in, you don't have an user_id yet.
]);
return back()->with('success', 'Add comment succeeded');
}
web.php Route here:
Route::post('/posts/{post}/comments', 'CommentsController#store')->name('addComment');
Basically auth middleware intercepted my form data submit, I want to go across the auth middleware with my form data. Not lost them after logging in.

Here is the solution.A little tricky.Save comment to the session first before go to auth middleware.After logging in, GET that route to create comment.
Route:
Route::get('/posts/{post}/comments', 'CommentsController#store')->name('addComment');
Route::post('/posts/{post}/comments', 'CommentsController#commentSave');
Comments controller:
public function __construct()
{
$this->middleware('auth', ['except' => ['commentSave']]);
}
public function commentSave(Request $request){
$url = \URL::previous();
session(['comment' => $request->input('body')]);
return redirect("$url/comments");
}
public function store(Post $post){
if(session('comment')){
$comment = Comment::create([
'body' => session('comment'),
'post_id' => $post->id,
'user_id' => auth()->user()->id
]);
session(['comment' => null]);
return redirect("posts/$post->id")->with('success', 'Add comment succeeded');
}
return redirect("posts/$post->id");
}

I think the solution to your problem is here:
https://laravel.com/docs/5.7/session#storing-data

Related

How can I validate the request user in Laravel?

I am sending a update request like:
Route::put('user/{user}/edit-user-education', 'UpdateUserEducationController#editUserEducation');
My controller is :
class UpdateUserEducationController extends Controller
{
public function editUserEducation(UserEducation $education, User $user, EditUserEducationRequest $request)
{
$education->school = $request->school;
$education->degree = $request->degree;
$education->user_id = $user->id; // here to validate
$education->save();
return response()->json([
'message' => 'Education Updated'
]);
}
}
Now how I can validate the request user_id with the user_id already in inserted in DB ? I want to ensure that the only user can update the record who created that one.
How to do so ? Thanks in advance
Check out the docs on validation here:
https://laravel.com/docs/8.x/validation
Specifically, I think you want the exists rule:
https://laravel.com/docs/8.x/validation#rule-exists
The quick and dirty way is to add your validation in the controller but there are some better methods as explained in the docs. I usually opt for Form Requests, which it looks like you've already done as your request is an instance of EditUserEducationRequest.
In the controller you can add:
$validated = $EditUserEducationRequest->validate([
'user_id' => 'required|exists:users',
]);
I assume your user table is called users.
You could alternatively state the exists validation rule for user_id in the rules array of your Form Request as per the docs.
EDIT:
I actually missed a requirement in your original post that is that the user sending the request must be the same user as the one being updated.
That can be handled in the the authorize method of your form request with something like:
public function authorize()
{
return $this->user()->id == $this->user_id;
}
Simply make a check that current user is the same user who is trying to update record.
class UpdateUserEducationController extends Controller
{
public function editUserEducation(UserEducation $education, User $user, EditUserEducationRequest $request)
{
if($user->id==Auth::user()->id){
$education->school = $request->school;
$education->degree = $request->degree;
$education->user_id = $user->id; // here to validate
$education->save();
return response()->json([
'message' => 'Education Updated'
]);
}
else{
return response()->json([
'error' => 'Invalid User'
]);
}
}
}

How do i redirect back to a page after login for some pages?

I am trying to redirect back to some page like my pricing page after login in laravel but it redirect back to previous pages even the ones that I dont want it to redirect back to.
public function login()
{
Session::put('url.intended',URL::previous());
return view('login');
}
public function loginPost()
{
if ($this->auth->attempt(array('email' => Input::get('email'), 'password' => Input::get('password')))){
return Redirect::to(Session::get('url.intended'));
}
return back();
}
You don't need to build login logic by yourself in laravel unless you want to , laravel provide pre-built auth scaffolding which you can use !
But what you are asking to redirect back for that you should use
return back();
At the ending of your function not at the ending of your class.
if ($this->auth->attempt(array('email' => Input::get('email'), 'password' => Input::get('password')))){
if(!empty($request->session()->get('url.intended'))){
return redirect($request->session()->get('url.intended'));
}else{
return redirect()->route('dashboard');
}
}

Router redirecting to the another page

I have route like
Route::get('admin/selfcontacteditdata','SelfcontectController#edit')->name('selfcontectedit');
Route::post('admin/selfcontactupdatedata','SelfcontectController#update')->name('selfcontectupdate');
If i just go to my browser and right admin/selfcontacteditdata it redirect me to
admin/newsshowdata
And my index function is
public function __construct()
{
return $this->middleware('auth');
}
public function index()
{
request()->validate([
'email' => 'required',
'mobileno' => 'required',
'facebook'=>'required',
'google'=>'required',
'map'=>'required',
]);
$data = selfcontect::find(1);
return view('/admin/selfcontectedit',compact('data'));
}
And my middleware is
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('login');
}
}
My rest admin routes are working fine.
I had the same problem but I was writing table name wrong and my file was not saved as .blade please check are you also doing the same thing and there is no meaning of validation in edit function your edit function must be like
public function edit()
{
$data = selfcontect::find(1);
return view('/admin/selfcontectedit',compact('data'));
}
and your function name should be edit
You should use Accept key not Content/type
You can't redirect through view, actually your are calling view.
Correct syntax is
return view('view_name',compact('data'));
If you want to redirect to any route you have to call like this
return redirect()->to('admin/selfcontacteditdata');
Redirect to a Route
If in your routes.php file you have a route with a name, you can redirect a user to this particular route, whatever its URL is:
app/Http/routes.php:
get('books', ['as' => 'books_list', 'uses' => 'BooksController#index']);
app/Http/Controllers/SomeController.php
return redirect()->route('books');
This is really useful if in the future you want to change the URL structure – all you would need to change is routes.php (for example, get(‘books’, … to get(‘books_list’, …), and all the redirects would refer to that route and therefore would change automatically.
And you can also use parameters for the routes, if you have any:
app/Http/routes.php:
get('book/{id}', ['as' => 'book_view', 'uses' => 'BooksController#show']);
app/Http/Controllers/SomeController.php
return redirect()->route('book_view', 1);
In case of more parameters – you can use an array:
app/Http/routes.php:
get('book/{category}/{id}', ['as' => 'book_view', 'uses' =>
'BooksController#show']);
app/Http/Controllers/SomeController.php
return redirect()->route('book_view', [513, 1]);
Or you can specify names of the parameters:
return redirect()->route('book_view', ['category'=>513, 'id'=>1]);

Laravel 5.1, passing my ID

I'm trying to pass an ID of a past and insert it into another database.
I got a page with shows posts like this
/posts/{id}
. From there on i want to add a comment section, so i got my form set up like this:
<form method="POST" action="/posts/{{ $post->id }}/comments">
(When i inspect the code, it inserts the right id and the "{{ $posts->id }}" spot.
inside my routes.php i got the folling route:
Route::post('/posts/{post}/comments', 'CommentsController#store');
and inside CommentsController.php i got the following
public function store(Post $post)
{
Comment::create([
'body' => request('body'),
'post_id' => $post->id
]);
return back();
}
When ever i try to add a comment i get this error:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'post_id'
cannot be null
When i change my code from CommentsController.php to this:
'post_id' => "2"
it works fine (but the comment will always be added at post with ID 2)
I can't seem to find out why my id wont go trough.
Anny help with this?
Try this
public function store(Request $request, Post $post)
{
$comment= new Comment;
$comment->body = $request->body;
$comment->post_id = $post->id;
$comment->save();
return back();
}
The route model binding allows you to convert the Post ID passed into the route into the actual post object in the controller method. It may even work smoother if you use a relationship between a post and a comment, like so:
public function store(Request $request, Post $post)
{
$post->comments->create([
'body' => $request->body
]);
return back();
}
Inside post model
public function comments()
{
return $this->hasMany('App\Comment','post_id');
}

How to add multiple route filters in Laravel 4.2 while using role:permission pattern?

I am having issues with using multiple route filters in Laravel 4.2 while using the pattern role:permission. I've attached my code below.
This doesn't work at all. When I change roles, it always give one 403 unauthorized. I want both moderator and administrator to access this route.
Perhaps there's a way to tell Laravel, "if the logged in user is either an administrator OR a moderator, then let them access this route".
Route::get('engage', [
'as' => 'engage_path',
'before' => 'role:administrator',
'before' => 'role:moderator',
'uses' => 'ManagementController#showEngagement'
]);
This is my role filter.
Route::filter('role', function($route, $request, $role)
{
if (Auth::guest() or ! Auth::user()->hasRole($role))
{
return Response::make('Unauthorized', 403);
}
});
I suggest you use some kind of delimiter, like a ; to pass in multiple roles.
'before' => 'role:administrator;moderator'
And change the filter:
Route::filter('role', function($route, $request, $value)
{
if(Auth::check()){
$user = Auth::user();
$roles = explode(';', $value);
foreach($roles as $role){
if($user->hasRole($role)){
return;
}
}
}
return Response::make('Unauthorized', 403);
});

Resources