Laravel Socialite - Use socialite to fill in fields and redirect back to the form without losing other information - laravel

I have a website, which has a form. Within the form, I have a button linked to socialite where a user can click on it and it will retrieve the name and email from Facebook. Then, I redirect the user back to the form to either fill in the remaining information or submit the form.
However, all of the other information is lost upon return to the page.
I have tried to pass a 'Request $request' within the function. However, it never actually gets the information as the button isn't exactly submitting the form.
Is there any way of ensuring that the previous information is pushed through to the Route and that this information is then pushed back to the redirect?
Here is my code so far:
web.php
Route::get('login/{service}', 'Auth\LoginController#redirectToProvider')->name('social');
Route::get('login/{service}/callback', 'Auth\LoginController#handleProviderCallback');
LoginController.php
public function handleProviderCallback(Request $request, $service)
{
$user = Socialite::driver($service)->stateless()->user();
return redirect()->back()
->with(['social' => 'social', 'name' => $user->name, 'email' => $user->email])
->withInput($request->all);
}
(Note: within the view, I am, of course, using {{ old('input_name') }} to get the inputs whenever the form fails after submission.)
Is there any way to get the information from Socialite and return back to the form without losing the previous information?
All suggestions, help, and comments are highly appreciated :)
Thanks!!

The problem is when the user is redirected to social provider, say facebook, the form data will not in that request, so when facebook redirects to the callback you will not find the form data there! ( facebook will not carry it for you )
You likely need to use some javascript here. look at hellojs

Related

Laravel 5/ Form security (require clarification)

Not entirely confident I have understood security in Laravel forms enough. For example, if a form contains
<input type="hidden" name="user_id">
then obviously a hacker could change the value before submitting an update.
While I have looked here at CSRF, I've not fully understood if this is enough protection?
E.g. Taking the above, if I go to a site and open a form to edit a record I'm permitted to view but not change, and maliciously alter the "user_id", is it enough that the form is protected with {{ csrf_field() }} or must I employ some further security such as Crypt::encrypt($id) to hide the user_id (held in a database) and Crypt::decrypt($id)?
Is it considered a bad practice to expose a row id (like a user id) in a client browser (even though everything is sent over https)?
Many Thanks
No, it's not enough to use just CSRF token in this case. You also need to use policies, guards, middleware to protect your app.
In this case, someone can alter the user_id if you read it from the form and use after that, so you need to use a policy like this one to protect data (this example is from the docs):
public function update(User $user, Post $post)
{
return $user->id === $post->user_id;
}
Also, when you need to use user ID, always use auth()->id() or auth()->user() if you need whole object. Never read user ID from the form.
The Laravel framework stores the value of this CSRF field like a session variable and matches it when you submit it.
When you submit the form Laravel checks that value from the session value stored. if there is a mismatch an error is thrown !
:)
CSRF token protect the site from cross-site requests, means an external user can't duplicate the form and send a post request. Laravel create a random session token which we place in the hidden field using csrf_field() or Session::token() function. Laravel checks the session with hidden field value from the form before processing the form.
Try removing the form action. It should work.

How to return to intended page in this case

I have the typical scenario of an online newspaper where you have the article and below a form to comment, but where you need to login to comment. So on clicking it takes you to the log page and it should return you to that page once you have authenticated.
So, because the form is part of a page that the user can see without being logged in, I cannot write the middleware for that page created by a PostController, (get route).
The CommentController only has one method, which is the store one for the Form. so, of course, if I placed a middleware for that controller, it would fail because although it would indeed take you to the login page on clicking the submit button, the Intended URL saved would be that Post for the form, so on returning after authenticating, it would take you to a non existent URL page under the name of the Post route for that Form.
I have read about Auth::guards and the like but could not come clear with it,
This
Laravel 5 - After login redirect back to previous page
asks exactly the same question that I do, it is the same scenario, but I dont see how his answer works, because defining a protected variable (and I have that already) like protected $redirectTo in the Auth controller only tells where to go after authenticating, and it is only a fixed route, in my case it takes you to the dashboard. But I dont want to be taken to the dashboard, it has to return to the page where the article and the comment form are.
I found the solution at Laracasts. I must say I really dont understand it, but it works. It adds two functions to the AuthController.
https://laracasts.com/discuss/channels/laravel/redirect-to-page-where-login-button-was-clicked
public function showLoginForm()
{
if(!session()->has('from')){
session()->put('from', url()->previous());
}
return view('auth.login');
}
public function authenticated($request,$user)
{
return redirect(session()->pull('from',$this->redirectTo));
}
It's been a while since i've done this, but this should work normally.
You could add a GET param in your link from the comment section to login page.
http://....com/login?intended=http://yourredirectlink.com/#form
Put the intended url in in the session variable url.intended and after login you redirect like so
Redirect::intended('/');
This will redirect back to the the url '/' if the session variable is not available.

How do we protect our post data processing method in CodeIgniter controller from the external form?

I'm working on a small project with CodeIgniter which handling some post data submitted from the admin form page.
I do transfer the post data to a method in my controller and send it to the database.
Its working all the time.
Im thinking, what if someone make an external form with the exact same inputs name and action attribute with mine in the admin page (I dont know how to figure the inputs name out but this is just my wonder), and try to post some data to the controller?
I try to use session but I wonder if there are any way to protect that kind of inject method?
you can try before your form_validator with
if( $_SERVER['HTTP_REFERER'] == base_url()){
//form validator
}
else{
$this->session->set_flashdata('warning', 'You try to enter from an external web without permission');
redirect(base_url(), 'refresh');
}
There are a couple of things you can do.
First, since this is an admin only page I assume you have some kind of login and user verification in place.
You can use session data to store the successful admin login.
//admin log in OK
$this->session->set_userdata('admin_logged_in', TRUE);
In the method that processes the form post, confirm the user is logged in
if($this->session->userdata('admin_logged_in') !== TRUE)
{
redirect('somewhere_else');
return; //here in case the redirect call doesn't work
}
Second, since you are 'posting' to this page confirm that is the method the server has received - it MUST be post. If you are using CI version => 3.0 the do this
if($this->input->method() !== 'post')
{
//somebody is trying to fool you
redirect('somewhere_else');
return; //here in case the redirect call doesn't work
}
If you are using an earlier version of CI (before 3.0.x) do this
if(strtolower($this->server('REQUEST_METHOD') !== 'post')
{
//somebody is trying to fool you
redirect('somewhere_else');
return; //here in case the redirect call doesn't work
}
You also might want to consider the case where the session info checks out but it was not a POST request. That is very suspicious to me and it might be wise to destroy the session before redirecting.

Laravel 5 - Deal with controller validation and RESTful clients like Postman

I am using laravel's RESTful resource routes and controllers.
I testing my api with PostMan and/or RestClient(firefox)
Everything was fine before I added laravel's controller validation. Now it respond with very strange responses like: status code 0, or even executes the code with not valid data. Or even shows strange results taken from the database (which are not included to the controller at all).
That's creepy.
For example:
public function store(Request $request) {
$this->validate($request, [
'room_id' => 'required|integer',
'body' => 'required'
]);
exit; // Stop the process after the validation...
// ... Logic to STORE the MESSAGE in the database ...
return response(null, 204);
}
This store function must only validate the data and respond with an error if validation fails,
But when I execute it from PostMan, It returns response with list of all rooms which belongs to this user. This is creepy, I cannot realize why this is happening.
When I use the jQuery.ajax() method with the same request options, it works fine. It validates the data and stores the message in the database.
Question : Is there a way to deal with postman?
Question : Is PostMan dangerous? Since the server respond with database info (which is not included to the controller responses).
If you take a closer look at laravel's validation document it says that when data is submitted via HTML form,the validate method would redirect you to a previous page and the error would be flashed into the session, if the validation fails. Although, you will be able to access these error messages in your view using the $error variable. Therefore you will need to submit the data via ajax in-order to get the JSON error message.
When validatioin failed, Laravel needs to know you are sending ajax request or you explicitly want json respond, otherwise it redirects you to previous page.
You can check my answer here
https://stackoverflow.com/a/38478362/6246592

Registering routes with Laravel but make them unaccessible

I am trying to make a single page CRUD application with Laravel. I will use ajax to create, edit and delete my entity, and also to render partial views. The corresponding controller methods will process the information and return the views.
I want to register the routes so I can call the different methods when necessary. I don't see any other way:
However, registering them so I can do something like this {{ Form::open(['route' => ['cities.store', $city->id]]) }} will allow access via the URL, and I only want to make those routes accessible through the tools I am going to create in that one page CRUD.
I can only think of applying a before filter, but what would be the filter? Also, any other ideas on how I should approach this situtation?
I've had to do something similar with a web service I created. Basically, I wanted only my app to be able to access the routes I created.
What I ended up doing was adding a hashed key to each request being sent, then checking for this key value in the controller. So, only if the key is present and matches the one sent would you then process the request.
Or, if you're using forms, you could do something like the following:
//check if request was sent from our form
if ( Session::token() !== Input::get( '_token' ) ) {
return Response::json( array(
'msg' => 'Unauthorized access attempt'
) );
}
Hope this helps.
another way that doesnt need tokens but is less secure, you got to know what you need,
is using laravels request information
if (Request::ajax())
{
//your action
}else{
//error
}
note this only works when your application always uses ajax you could even type this in your before filter and add it to all needed routes

Resources