No hashing on Password field in Laravel seeder - php

I've recently inherited a project from a Laravel developer to look at. Unfortunately, when I migrate and seed the user table, the password ciphering is not working, as follows:
public function run()
{
DB::table('users')->insert([
'email' => 'admin#site.co.uk',
'first_name' => 'Site',
'last_name' => 'Admin',
'username' => 'admin',
'password' => 'localhostPassword'
]);
}
When I run php artisan migrate --seed the password field is the string literal as above, and when I try to sign in it tells me that my password credentials are incorrect.
As I'm not an Artisan Laravel developer I'm not sure where to start, but I'm expecting the password field to be hashed like this $2y$10$u/FcKFPKsgRs8whJZ6ODAO90qllmGjqROnkmuQnxcpynG6WaIbX8e, which is what is generated when I use the register form in the current code base.

You need to hash it before storing it:
use Illuminate\Support\Facades\Hash; // <-- import it at the top
//
public function run()
{
DB::table('users')->insert([
'email' => 'admin#site.co.uk',
'first_name' => 'Site',
'last_name' => 'Admin',
'username' => 'admin',
'password' => Hash::make('localhostPassword') // <---- check this
]);
}
Note: An alternative is to use the bcrypt() helper instead of the Hash::make() method.
Chech the documentation regarding this aspect:
Basic Usage
You may hash a password by calling the make method on the Hash
facade:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\Http\Controllers\Controller;
class UpdatePasswordController extends Controller
{
/**
* Update the password for the user.
*
* #param Request $request
* #return Response
*/
public function update(Request $request)
{
// Validate the new password length...
$request->user()->fill([
'password' => Hash::make($request->newPassword)
])->save();
}
}

You have to manually bcrypt the password like below
public function run()
{
DB::table('users')->insert([
'email' => 'admin#site.co.uk',
'first_name' => 'Site',
'last_name' => 'Admin',
'username' => 'admin',
'password' => bcrypt('localhostPassword')
]);
}

Related

Laravel: 2 Registration Forms with Login

I'm working in Laravel 8 and like to know what's the best approach for logging in with the 2 registration forms I have already set up. The forms are set up with just validation, but trying to figure out how to have a login for these different sign-up roles, which will go to 2 different dashboards.
This is where I'm at with my code...
web.php
// Profile
Route::get('/register/profile', [RegisterProfileController::class, 'index'])->name('register_profile');
Route::post('/register/profile', [RegisterProfileController::class, 'store']);
// Business
Route::get('/register/business', [RegisterBusinessController::class, 'index'])->name('register_business');
Route::post('/register/business', [RegisterBusinessController::class, 'store']);
RegisterProfileController.php (with just validation)
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class RegisterIndividualController extends Controller
{
public function index()
{
return view('auth.register_profile');
}
public function store(Request $request)
{
$this->validate($request, [
'firstname' => 'required|max:255',
'lastname' => 'required|max:255',
'username' => 'required|min:8|max:60|alpha_num',
'email' => 'required|email|max:255',
'phone' => 'required|digits:10',
'city' => 'required|max:100',
'state' => 'required',
'zip' => 'required|digits:5',
'password' => 'required|confirmed'
]
}
}
RegisterBusinessController.php (with just validation)
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class RegisterBusinessController extends Controller
{
public function index()
{
return view('auth.register_business');
}
public function store(Request $request)
{
$this->validate($request, [
'businessname' => 'required|max:255',
'firstname' => 'required|max:255',
'lastname' => 'required|max:255',
'username' => 'required|min:8|max:60||alpha_num',
'businessemail' => 'required|email|max:255',
'phone' => 'required|digits:10',
'address' => 'required|max:255',
'city' => 'required|max:100',
'state' => 'required',
'zip' => 'required|digits:5',
'website' => 'required|url',
'industry' => 'required',
'password' => 'required|confirmed'
]
}
}
I created the migration schema for each:
2021_10_26_011205_create_individuals_table.php
2021_10_26_011224_create_businesses_table.php
If you want to use Laravel's built-in authentication system, then you can set up your own authentication guards, which would let you log in using your existing models (here's a Stack Overflow answer with an example of setting up authentication with multiple models). Once you have this set up, you could then use the relevant guard in your login controller:
// Get the business model
$business = Business::where('businessemail', $request->input('businessemail'))->firstOrFail();
// Verify the password
if (Hash::check($request->input('password'), $business->password)) {
// Log in
Auth::guard('business')->login($business);
} else {
// Incorrect password
}
Additionally, since it looks like you're still in the early stages of development, I would recommend reconsidering your authentication model. Instead of having two completely different tables, and needing to set up two different authentication guards, I would recommend using the User model for both individuals and businesses, and adding an account_type column. You could then create a business_profiles table, which links to the users table via a user_id column, which would hold the business-only information (businessname, industry, and website).

How to stop auto login after registration in Laravel 8 breeze

Hi I am fairly new to Laravel framework. I am trying to create a separate controller replicating the registeredusercontroller.php in laravel breeze to have a function for admin user to be able to add new users. But I am having trouble with auto login and as soon as I add a new user it automatically logs in to the new user. How can I stop this from happening. I saw posts stating to remove
$this->guard()->login($user);
but when I see the app/Auth/registeredusercontroller.php I don't see that line.
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|confirmed|min:8',
]);
Auth::login($user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]));
$user->attachRole('user');
event(new Registered($user));
return redirect(RouteServiceProvider::HOME);
}
how can I stop the auto login after registration.
Any help is greatly appreciated.
You can do this proper way like using custom request handler.
The parameter you need is name, email, password.
So add CreateUserRequest above app/http/request
<?php
namespace App\Http\Requests;
use Illuminate\Http\Request;
class CreateUserRequest extends Request
{
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|confirmed|min:8',
];
}
}
And into your controller just do this;
public function store(CreateUserRequest $request) // add your custom request as a parameter
$user = User::create($request)
These codes makes your code structure clear and clean.

Auth::attempt always return false even with proper input

Here are the facades I used
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
I've successfully created user signup page with hashed password using bcrypt.
//Get singnup view
public function getSignup()
{
return view('user.signup');
}
//Process signup
public function postSignup(Request $request)
{
$this->validate($request, [
'email' => 'email|required|unique:users',
'password' => 'required|min:4'
]);
$user = new User([
'email' => $request->input('email'),
'password' => bcrypt($request->input('password')),
]);
$user->save();
return redirect()->route('product.index');
}
And now I'm stuck at the signin page. The Auth::attempt always return false. I even tried to store a plain password in my database and signin without bcrypt but it still returned false. I have no idea where I'm wrong right now.
//Get signin view
public function getSignin()
{
return view('user.signin');
}
//Process signin
public function postSignin(Request $request)
{
$this->validate($request, [
'email' => 'email|required',
'password' => 'required|min:4'
]);
$credentials = array(
'email' => $request->input('email'),
'password' => bcrypt($request->input('password'))
);
if(Auth::attempt($credentials))
{
return redirect()->route('user.profile');
}
return redirect()->route('product.index');
}
You don't need bcrypt() in Auth::attempt(). Remove it and try again.
In config\auth, change guard driver setting is set to api.
'defaults' => [
'guards' => 'api',
'passwords' => 'users'
]
But Laravel doesn't support attempt() function with guard api. Thus, you should use some packages like Passport (You can reference here)
Or simplier, just configure you guard driver with Auth::guard('api')->attempt($credentials)
Hope this solve your problem.

test if user is logged in laravel 5.7

I am making a test but it fails when it tries to check if a user is logged in:
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Auth;
use App\User;
class RegisterTest extends TestCase
{
use RefreshDatabase;
/*.....
more test about registering
....*/
/** #test */
function redirect_to_home_page_and_logged_in_after_login()
{
$user = factory(User::class)->create([
'name' => 'Test',
'email' => 'test#hotmail.com',
'password' => '123456'
]);
$response = $this->post('login', [
'email' => 'test#hotmail.com',
'password' => '123456'
]);
//this works
$response->assertRedirect('/');
//this fails
$this->assertTrue(Auth::check());
}
}
And this is my controller HomeController:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class HomeController extends Controller
{
public function index()
{
if (Auth::check()){
return view('home');
}
return view('welcome');
}
}
And this is my routes/web.php
Route::get('/', 'HomeController#index');
Auth::routes();
I am not sure what I am doing wrong. What can I do?. I am using laravel 5.7 and phpunit 5.7.1
Also in my app/Htpp/Auth/LoginController.php I did this:
protected $redirectTo = '/';
Thank you.
In addition to hashing your password you could also just post to the register route and create a new account.
/** #test */
function redirect_to_home_page_and_logged_in_after_register()
{
$response = $this->post('register', [
'name' => 'Test',
'email' => 'test#hotmail.com',
'password' => '123456'
]);
//this works
$response->assertRedirect('/');
//this fails
$this->assertTrue(Auth::check());
}
I guess you may also have a requirement to do it both ways:
/** #test */
function redirect_to_home_page_and_logged_in_after_login()
{
$user = factory(User::class)->create([
'name' => 'Test',
'email' => 'test#hotmail.com',
// note you need to use the bcrypt function here to hash your password
'password' => bcrypt('123456')
]);
$response = $this->post('login', [
'name' => 'Test',
'email' => 'test#hotmail.com',
'password' => '123456'
]);
//this works
$response->assertRedirect('/');
//this fails
$this->assertTrue(Auth::check());
}
Creating a user requires you to take care of the hashing of the password.
You can simply do it by using php's password_hash function. And use Auth::login($user); to login.
Like so:
$user = User::create(['email' => 'r#o.b', 'password' => password_hash('123456', 1)]);
Auth::login($user); //You should be logged in :)

Laravel 5.5: Execute a method before registration

I'm using the default laravel authentication. Every user who registeres in my site needs a activation pin. The valid PINs are stored in a different table. Whenever a user registeres, I want to test if the PIN is valid or not. So, is there any method that I can override in RegisterController that executes before regstering the user?
Yes. You can override protected register method in RegisterController. This is a simple solution. I do this to validate params, save a new user, and force return JSON in one of my projects.
For example:
protected function register(Request $request)
{
$validator = Validator::make($request->all(), [
'first_name' => 'required',
'last_name' => 'required',
'email' => 'required|email|unique:users',
'phone' => 'required',
'pin' => 'required'
]);
//Check your PIN here, if it's wrong, append errors array
if ($validator->fails())
throw new ValidationFailed($validator->errors());
User::create([
'first_name' => $request->input('first_name'),
'last_name' => $request->input('last_name'),
'email' => $request->input('email'),
'phone' => $request->input('phone'),
'password' => bcrypt(str_random(10)),
'remember_token' => str_random(10),
]);
return ResponseJSON::make(trans('responses.registered'));
}
You can add a validation rule for validating the pin in the validator method like this :
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
'pin' => [
'required',
Rule::exists('pins')->where(function ($query) {
$query->where('Some condition');
}),
],
]);
}
I assume you have a table for pins called pins
extend the register function in user class:
public function register(Request $request)
{
event(new \App\Events\NewUserRegistered(Auth::user()));
return redirect($this->redirectPath());
}
NewUserRegistered:
namespace App\Events;
use App\Events\Event;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use App\User;
class NewUserRegistered extends Event
{
use SerializesModels;
public $userID;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct(User $userID)
{
//get whatever is massed in here's value in the id column
$this->id = $userID;
}
/**
* Get the channels the event should be broadcast on.
*
* #return array
*/
public function broadcastOn()
{
return [];
}
}

Categories