User password changes in Laravel 8 after a period of time post logout, maybe a day or more. When I look into the database, the password hash has changed. I used the default Laravel authentication and had this issue, so I wrote the login code below, but still, I have the issue.
LoginController
public function login(Request $request)
{
$email_username = filter_var($request->username, FILTER_VALIDATE_EMAIL) ?
'email' : 'username';
$request->merge([$email_username => $request->username]);
if (Auth::attempt($request->only($email_username, 'password'))) {
return redirect()->intended($this->redirectTo);
} else {
return view('auth.login')
->with('these credetials do not match our records.');
}
$user = User::where($email_username, $request->username)->get();
if ($user && Hash::check($request->password, $user->password)) {
$request->session()->regenerate();
auth()->login($user);
return redirect()->intended($this->redirectTo);
}
return redirect()->back();
}
User Model
class User extends Authenticatable
{
use HasFactory, Notifiable;
public function partners()
{
return $this->hasMany('App\Models\partner');
}
protected $fillable = [
'username',
'profilepic',
'firstname',
'lastname',
'password',
'email',
'title',
'phone',
];
protected $hidden = [
'password',
'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
}
and this is the method that registers user.
public function store(Request $request)
{
$request->validate([
'username' => ['required', 'string', 'max:255', 'unique:users'],
'profilepic' => ['required', 'image', 'mimes:jpeg,png,jpg,gif,svg,ico', 'max:2048'],
'firstname' => ['required', 'string', 'max:255'],
'lastname' => ['required', 'string', 'max:255'],
'password' => ['required', 'string', 'min:8'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'title' => ['required', 'string', 'max:255'],
'phone' => ['required', 'min:10'],
]);
if ($request->profilepic != null) {
$profilepic = $request->firstname . ' ' . $request->lastname . '.' . $request->profilepic->extension();
$request->profilepic->move(public_path('/global_assets/images/users/'), $profilepic);
}
$user = new User([
'username' => $request->get('username'),
'profilepic' => $profilepic,
'firstname' => $request->get('firstname'),
'lastname' => $request->get('lastname'),
'password' => Hash::make($request->get('password')),
'email' => $request->get('email'),
'title' => $request->get('title'),
'phone' => $request->get('phone'),
'isAdmin' => $request->get('isAdmin'),
'isActive' => $request->get('isActive'),
]);
$user->save();
return redirect()->back()->with('success', 'New user has been created.');
}
Related
This is my RegisterController (Laravel ui edited). please help me.
Is i have to add any other page to this question.
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:8', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\Models\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'name_of_firm' => $data['name_of_firm'],
'number' => $data['number'],
'address' => $data['address'],
]);
}
There is 2 case if name_of_firm is nullable or required
Case : 1
if name_of_firm is required
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:8', 'confirmed'],
'name_of_firm' => ['required']
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\Models\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'name_of_firm' => $data['name_of_firm'],
'number' => $data['number'],
'address' => $data['address'],
]);
}
Case : 2
if name_of_firm is nullable
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:8', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\Models\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'name_of_firm' => $data['name_of_firm'] ?? null, // make sure database is accept null value
'number' => $data['number'],
'address' => $data['address'],
]);
}
you should use data_get or Arr::get() helpers to solved not exists element:
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\Models\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'name_of_firm' => data_get($data, 'name_of_firm'),
'number' => data_get($data, 'number'),
'address' => data_get($data, 'address')],
]);
}
If I change validate by validator->fails return redirect..... I get error because login want an instance of $user and I send a response.
This defaults work well but not for me
public function create(array $input)
{
Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => $this->passwordRules(),
'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['required', 'accepted'] : '',
])->validate();
return User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]);
}
Thats give me a:
Illuminate\Auth\SessionGuard::login(): Argument #1 ($user) must be of type Illuminate\Contracts\Auth\Authenticatable, Illuminate\Http\RedirectResponse given, called in ....endor/laravel/fortify/src/Http/Controllers/RegisteredUserController.php on line 57
public function create(array $input)
{
$validator = Validator::make($input, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => $this->passwordRules(),
'terms' => Jetstream::hasTermsAndPrivacyPolicyFeature() ? ['required', 'accepted'] : '',
]);
if($validator->fails()) {
return Redirect::to(URL::previous() . "#my-anchor")->withInput()->with('error', $validator->messages()->first());
} //Thats I want
return User::create([
'name' => $input['name'],
'email' => $input['email'],
'password' => Hash::make($input['password']),
]);
}
I don't did this before but maybe you can find the way to customize it. The CreateNewUser is called in the RegisteredUserController's store method, and the first return an User's instance. So in this you can
if($validation->fails())
return $validation->messages()->first();
and in the store method
public function store(Request $request, CreatesNewUsers $creator): RegisterResponse
{
$user = $creator->create($request->all()));
if($user instanceof User::class) {
event(new Registered($user);
$this->guard->login($user);
return app(RegisterResponse::class);
} else
return Redirect::to(URL::previous()."#my-anchor")->withInput()->with('error', $user);
}
Try this, but I suggest you if works extends this Register controller and just modify this store method
I hope you can help me, I wanna customize the registercontroller from Laravel, I have this, but after the user is registered send me a JSON of data, how can I do for don't send me the JSON and redirect to the HomeController.
Thanks.
PD. Sorry for my English.
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => ['required', 'string', 'max:255'],
'nombre' => ['required', 'string', 'max:255','unique:users'],
'telefono' => ['required', 'numeric', 'max:99999999', 'min:00000000'],
'direccion' => ['required', 'string', 'max:255'],
'sueldo' => ['numeric','min:0.01','max:0.99'],
//'foto' => ['string', 'max:255'],
'email' => ['string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:4', 'confirmed'],
]);
if ($request->hasFile('foto')) {
$request = request();
$file = $request->file('foto');
$nom_imagen = time().".".$file->getClientOriginalExtension();
$upload_path = 'imagenes/';
$profile_image_url = $upload_path . $nom_imagen;
$success = $file->move($upload_path, $nom_imagen);
} else {
$nom_imagen = '';
}
return User::create([
'name' => $request->input('name'),
'nombre' => $request->input('nombre'),
'telefono' => $request->input('telefono'),
'direccion' => $request->input('direccion'),
'sueldo' => $request->input('sueldo'),
'email' => $request->input('email'),
'foto' => $nom_imagen,
'password' => Hash::make($request['password']),
return redirect()->action('HomeController#index'),
]);
}
Laravel 5.5: Execute a method before registration
HomeController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
return view('index');
}
}
You are returning the return value of User::create() which will be a User object which gets converted to json when returned as a response.
Also since your HomeController is protected by 'auth' middleware you need to login the user before redirecting to '/home'
use Illuminate\Support\Facades\Auth;
public function register(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => ['required', 'string', 'max:255'],
'nombre' => ['required', 'string', 'max:255','unique:users'],
'telefono' => ['required', 'numeric', 'max:99999999', 'min:00000000'],
'direccion' => ['required', 'string', 'max:255'],
'sueldo' => ['numeric','min:0.01','max:0.99'],
//'foto' => ['string', 'max:255'],
'email' => ['string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:4', 'confirmed'],
]);
if ($request->hasFile('foto')) {
$request = request();
$file = $request->file('foto');
$nom_imagen = time().".".$file->getClientOriginalExtension();
$upload_path = 'imagenes/';
$profile_image_url = $upload_path . $nom_imagen;
$success = $file->move($upload_path, $nom_imagen);
} else {
$nom_imagen = '';
}
$user = User::create([
'name' => $request->input('name'),
'nombre' => $request->input('nombre'),
'telefono' => $request->input('telefono'),
'direccion' => $request->input('direccion'),
'sueldo' => $request->input('sueldo'),
'email' => $request->input('email'),
'foto' => $nom_imagen,
'password' => Hash::make($request['password']),
]);
Auth::guard()->login($user);
return redirect('/home');
}
Move the redirect after create user , try like this
User::create([
'name' => $request->input('name'),
'nombre' =>$request->input('nombre'),
'telefono' => $request->input('telefono'),
'direccion' => $request->input('direccion'),
'sueldo' => $request->input('sueldo'),
'email' => $request->input('email'),
'foto' => $nom_imagen,
'password' => Hash::make($request['password'])
]);
return redirect()->action('HomeController#index'),
I have a user settings form with 4 fields - first and last name, date of birth and username. The username is unique field in the database. The issue that I run into is when I already have set your username but after that want to update the last name or first name it always throws an error that the username is already in use. Can I somehow check if the username hasn't been changed to not validate it? Only to validate the other fields?
public function update(Request $request)
{
$user = Auth::user();
$this->portfolioValidator($request->all())->validate();
$user->username = $request->username;
$user->contact->first_name = $request->first_name;
$user->contact->last_name = $request->last_name;
$user->contact->save();
$user->save();
return response()->json(['message' => 'The changes have been saved'], 201);
}
protected function portfolioValidator(array $data)
{
return Validator::make($data, [
'first_name' => ['required', 'string'],
'last_name' => ['required', 'string'],
'username' => ['required', 'string', 'min:4', 'max:30', 'unique:users'],
]);
}
You can update your unique rule to ignore the current user as described here:
use Illuminate\Validation\Rule;
protected function portfolioValidator(array $data)
{
return Validator::make($data, [
'first_name' => ['required', 'string'],
'last_name' => ['required', 'string'],
'username' => ['required', 'string', 'min:4', 'max:30', Rule::unique('users')->ignore(Auth::user()->id)],
]);
}
I'm using oauth2 and my table users is "coUsers" . I added this in my User Model
App\User
protected $table = 'coUsers';
public function getAuthPassword()
{
return $this->pass;
}
AuthController
public function login(Request $request)
{
$request->validate([
'usuario' => 'required|string|email',
'clave' => 'required|string',
//'remember_me' => 'boolean'
]);
$credentials = [
'usuario' => $request->get('usuario'),
'password' => $request->get('clave'),
];
if(!Auth::attempt($credentials)){
return response()->json([
'message' => 'Unauthorized'
], 401);
}
$user = $request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
if ($request->remember_me)
$token->expires_at = Carbon::now()->addWeeks(1);
$token->save();
return response()->json([
'access_token' => $tokenResult->accessToken,
'token_type' => 'Bearer',
'expires_at' => Carbon::parse($tokenResult->token->expires_at)->toDateTimeString()
]);
}
public function firstLogin(Request $request)
{
$request->validate([
'usuario' => 'required|string|email|unique:users',
'clave' => 'required|string',
'nuevaClave' => 'required|string'
]);
$user = User::where('usuario', $request['usuario'])
->where('clave', $request['clave'])
->first();
$user->clave = bcrypt($request['nuevaClave']);
$user->first_login = false;
$user->save();
return response()->json([
$user->toArray()
]);
}
Auth login works OK, but I want to use User::where in firstLogin.... I get this error:
Illuminate\Database\QueryException: SQLSTATE[42703]: Undefined column: 7 ERROR: column "usuario" does not exist
LINE 1: select count() as aggregate from "users" where "usuario" = ...
^ (SQL: select count() as aggregate from "users" where "usuario" = xxxxx#gmail.com) in file \vendor\laravel\framework\src\Illuminate\Database\Connection.php on line 669
Look in the users table instead of using the table that I indicated in the model.
You may change 'usuario' => 'required|string|email|unique:users', to 'usuario' => 'required|string|email|unique:coUsers', in your firstLogin method
You may also change this 'unique:users' in validator method inside your App\Http\Controllers\Auth\RegisterController
'email' => ['required', 'string', 'email', 'max:255', 'unique:users']
to
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:coUsers'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}