Retain session when login in with Laravel Socialite in google or reset id with previous one - laravel

I currently have a Laravel app that signs in using Socialite.
public function redirectToGoogle(Request $request)
{
return Socialite::driver('google')->stateless()->redirect();
}
When it loads and redirects I lose the previous session id.
I need that session id because it's loaded in my db to track some cart info.
Is there away I can retain the previous session id when Socialite loads the google driver?
I can also reset the session id since I have it in my db. However I don't know how to regenerate it with a custom string.
$request->session()->regenerate();
But passing it a custom string?
$request->session()->regenerate('some value');
session()->getId(); //does not regenerate 'some value'

I would setId like so:
session()->setId($myCustomId);
From here

Related

How to make custom authentication on Laravel?

I have a Laravel application, with a login form. I am using subdomains, for example: {{business_subdomain}}.laravel.test. The purpose of my application is create companies in my database, and make registered users login on their attached company and specific domain.
So in my web.php I declared the following:
Route::domain('{business_subdomain}.' . env('APP_URL'))->middleware(['business.subdomain'])->group(function ()
My database contains the following tables:
* Standard tables like users
* Businesses which contains id, name and subdomain
* Business_user which contains business_id and user_id
The business_id (business_user table) has a relationship with id (business table)
The user_id (business_user table) has a relationship with id (users table)
I created a middleware that checks the following:
$business = $request->user()->businesses->where('subdomain', $request->route('business_subdomain'))->first();
So the subdomain value (business table) must be the equal to the URL/route subdomain value, otherwise when you login, you will get an 403 page.
So what I want to achieve: When a user has an account, but is not attached to the right company/business, I want to display the standard authentication error: These credentials do not match our records.
I've tried to use the code in my middleware on the LoginController and override almost every function separately, but it didn't work.
Do I need to override Laravel authentication functions, do I need to create another middleware or use Guards?
The laravel authentication login order (the order the application uses for logging in a user) seems very confusing for me.
Maybe someone can provide me with more information or help me out!
I tried to use the code in my middleware on the LoginController and override almost every function separately, but it didn't work.
Sounds like you might be looking for multi-tenancy. There are a couple different packages available, both for single and multi-database setups.
Here are some very informative slides on the topic, specific to Laravel. And an excellent article for more detail.
We have a similar application with subdomain routing using torzer/awesome-landlord. The tenant package ensures that login will only search for users of the correct tenant.
To set the correct tenant we added a middleware (App is the tenant, in your case it would be Business):
public function handle($request, Closure $next)
{
$subdomain = $this->getSubdomain($request->server('HTTP_HOST'));
if ($subdomain) {
$app = App::getBySlug($subdomain);
abort_if(!$app, 404);
$this->tenantManager->addTenant($app);
} else {
// empty or generic subdomain
// this is OK as long as there is no user
if ($user = $request->user()) {
return $this->redirectToUserAppSubdomain($request, $user);
}
}
return $next($request);
}

How do I manually send a password reset request in Laravel 5.4?

I would like to manually send a password reset request to a specific user (not the one currently logged in) from within a controller. I did some digging around in the Laravel code and it seems like I should be calling postEmail(Request $request) in ResetsPasswords, but I can't seem to figure out how to get access to the right PasswordController instance to call it.
Seems like you are admin, so from your end, you can set a column in database (is_active), and change that to 0, and check when user logged in if is_active == 0. If it's 0, allow him to set a new password, then make a hash of new password and change is_active to 1

Laravel session variables get Null, once redirect to Payment Gateway and return back

I found some related questions, but they don't have enough explanations/solutions for my problem. I'm integrating Paycorp payment gateway with an existing project. In PaymentController.php I put all the hotel IPG settings in an array and put in session. Once I put it in session, I try to print it with vardump, it is working, it is in the session! Then I initiate the payment and redirect to generated url. It redirects to Paycorp payment, I provide the card details and submit. When it returns to PaymentCompleteController.php I need to complete the payment and I Need the Hotel IPG settings which I've put in session. When I tried to get it, there is nothing and it is NULL.
PaymentController.php
$params['something1'] = $something1;
$params['something2'] = $something2;
$params['something3'] = $something3;
$params['something4'] = $something4;
Session::put(SampleModel::PARAMS, $params);
//At this point Params are in the session
//var_dump(Session::get(SampleModel::PARAMS)); exit();
//Initiate Payment and Redirect to URL
Once the card details are given and submitted, it will redirect back to
PaymentCompleteController.php
vardump(Session::get(SampleModel::PARAMS)); exit();
In PaymentCompleteController.php session variable is null. But the variable put before the PaymentController.php are still there.
When a Laravel application lifecycle starts, any value put in Session are not yet stored until the application lifecycle ends. The redirect is preventing that.
Persist the session values right after you call put():
Session::put(SampleModel::PARAMS, $params);
Session::save();

Laravel - user login

I use Laravel 5.4 and need to login user in my system. I have next login.blade.php
where i have email and password field. In my controller I have next
protected function log() {
$email=Input::get('email');
$pass=Input::get('password');
$user = DB::select("SELECT * FROM users where email = '".$email."' and password = '".$pass."'");
foreach($user as $users){
if(Input::get('email') == $users->email){
return redirect('/');
}else{
return view('site.warning');
}
}
}
How can I return logged user in my redirect('/') and show them in my site.
Any idea?
Use the attempt() method:
if (Auth::attempt(['email' => $request->email, 'password' => $request->password])) {
From the docs:
The attempt method accepts an array of key / value pairs as its first argument. The values in the array will be used to find the user in your database table. So, in the example above, the user will be retrieved by the value of the email column. If the user is found, the hashed password stored in the database will be compared with the password value passed to the method via the array.
This method will work for you if you're using bcrypt() or Hash::make() to generate password hash.
Please do not create your own login system!
Now that's out of the way the explanation.
There is (almost) no good reason to create your own login system, as your code already showed. Your current code is very VERY insecure due to storing passwords in plain text. Please read up on resent security advice.
The even better option is using Laravels build-in auth.
https://laravel.com/docs/5.4/authentication
If you do try to use this build-in authentication methods you will be able to get the current authenticated user by using Auth::user() this can be used in your blade files as well as in your controllers.
You cannot (maybe you can) but you certainly should't store user's password unhashed. Laravel has build artisan command: php artisan make:auth. You may use it, and retrieve him in the show method for example (thro the URL, passing id). Or just retrieve him via Auth::user(). Planty of choices.

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.

Resources