Laravel Input Validaiton Exists with username or email - php

how to make correct validation if i have input from where i can sign in with username or email, i want to if user will text username in field, it check if this username doesnt exist, then fail, also if he will choose to use email to sign in, then it will check if email doesnt exist then fail. (login form have only 2 inputs, login and password, in login u can text username or email)
my rule =
public function rules()
{
return [
'user' => 'required|min:3|exists:users,username,email]',
'password' => 'required',
];
}

You can use custom login as :
public function login(Request $request)
{
$request->validate([
'user' => 'required|min:3]',
'password' => 'required',
]);
}
$userName_or_Email = $request->user;
$password = $request->password;
$user = User::where('username',$userName_or_Email)->first();
if(empty($user)){
$user = User::where('email',$userName_or_Email)->first();
}
if(empty($user)){
return new Response()->with('error','Username or email not available in database');
}
if(Hash::check($password, $user->password)){
// Login successful code
}else{
return new Response()->with('error','Username or email not available in database');
}

Related

Not able to authenticate in laravel

I have this error in Laravel latest for authentication
Argument 2 passed to Illuminate\Auth\SessionGuard::__construct() must
be an instance of Illuminate\Contracts\Auth\UserProvider, null given,
called in
G:\xampp\htdocs\newrestaurantcrm\vendor\laravel\framework\src\Illuminate\Auth\AuthManager.php
can anyone give me an idea about this error why this error is occurring?
I am using below code for authentication in my Auth\AuthController.php file
protected function login(Request $request) {
$email = $request->email;
$password = bcrypt($request->password);
if (Auth::login(['email' => $email, 'password' => $password])) {
return redirect()->intended('/admin/dashboard');
}
}
Change your code to
public function login(Request $request) {
$email = $request->get('email');
$password = $request->get('password');
if (Auth::attempt(['email' => $email, 'password' => $password])) {
return redirect()->intended('/admin/dashboard');
}
}
I changed the protected to public, Auth::login() to Auth::attempt(). If you use login, you will actually have to pass the User object you like to login as. You do not need to encrypt the password to pass to attempt and. To make this simpler you can write
public function login(Request $request) {
if (Auth::attempt($request->only('email', 'password'))) {
return redirect()->intended('/admin/dashboard');
}
}
This of course assumes that your form has correct name for fields, email and password and also has same field email and password in users table as well.
When you are authenticate user against email and password then use Auth::attempt or Auth::once (For single request). When we have user instance and we want to login with that user instance then we use Auth::login. For your case use Auth::attempt like this
public function login(Request $request) {
$email = $request->email;
$password = bcrypt($request->password);
if (Auth::attempt(['email' => $email, 'password' => $password])) {
return redirect()->intended('/admin/dashboard');
}
}
Details: https://laravel.com/docs/5.6/authentication#included-authenticating

Laravel 5 custom login with username OR email using the Attempt method

In my laravel app, at the start I had decided to create my own custom login controller, rather than use the base one.
public function postSignin(Request $request, AppMailer $mailer) {
$this->validate($request, [
'email' => 'required',
'password' => 'required',
]);
if (!Auth::attempt($request->only(['email', 'password']), $request->has('remember'))) {
return redirect()->back()->with('info', 'Could not sign you in with those details.');
}
if (Auth::attempt(['email' => $request->input('email'), 'password' => $request->input('password'), 'verified' => 0]))
{
$mailer->sendEmailConfirmationTo(Auth::user());
Auth::logout();
return redirect()->back()->with('info', 'Email verification required.');
}
Auth::user()->last_login = new DateTime();
Auth::user()->save();
return redirect()->back()->with('info', 'You are now signed in.');
}
And now I want to edit this so that users can also login with their usernames and not just their emails, using the same field. However, the attempt method is confusing. It seems to expect an email even after I switch the values around.
The Auth documentation isn't very helpful in this case either. It asks me to add this:
public function username()
{
return 'username';
}
in the login controller, but obviously this is for a default setup.
You can use the 'FILTER_VALIDATE_EMAIL' checker.
$username = $request->get('username');
$password = $request->get('password');
$remember_me = $request->get('remember_me','1');
$field = filter_var($username,FILTER_VALIDATE_EMAIL)? 'email': 'username';
if(Auth::attempt([$field => $username,'password' => $password],$remember_me)){
//Auth successful here
}
Meaning FILTER_VALIDATE_EMAIL do check the string whether it is in email format or not.
I hope this sample code helps you.
-ken

Allow login using username or email in Laravel 5.4

Now I've followed the Laravel documentation on how to allow usernames during authentication, but it takes away the ability to use the email. I want to allow users to use their username or email to login. How do I go about this?
I've added this code to the LoginController as per Laravel's Documentation and it only allows username for login. I want it to accept username or email for login.
public function username () {
return 'username';
}
I think a simpler way is to just override the username method in LoginController:
public function username()
{
$login = request()->input('login');
$field = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
request()->merge([$field => $login]);
return $field;
}
Follow instructions from this link: https://laravel.com/docs/5.4/authentication#authenticating-users
Then you can check for the user input like this
$username = $request->username; //the input field has name='username' in form
if(filter_var($username, FILTER_VALIDATE_EMAIL)) {
//user sent their email
Auth::attempt(['email' => $username, 'password' => $password]);
} else {
//they sent their username instead
Auth::attempt(['username' => $username, 'password' => $password]);
}
//was any of those correct ?
if ( Auth::check() ) {
//send them where they are going
return redirect()->intended('dashboard');
}
//Nope, something wrong during authentication
return redirect()->back()->withErrors([
'credentials' => 'Please, check your credentials'
]);
This is just a sample. THere are countless various approaches you can take to accomplish the same.
Open your LoginController.php file.
Add this reference
use Illuminate\Http\Request;
And override the credentials method
protected function credentials(Request $request)
{
$field = filter_var($request->get($this->username()), FILTER_VALIDATE_EMAIL)
? 'email'
: 'username';
return [
$field => $request->get($this->username()),
'password' => $request->password,
];
}
Successfully tested in Laravel 5.7.11
You need to override protected function attemptLogin(Request $request) method from \Illuminate\Foundation\Auth\AuthenticatesUsers Trait in your LoginController
i.e. in my LoginController class
protected function attemptLogin(Request $request) {
$identity = $request->get("usernameOrEmail");
$password = $request->get("password");
return \Auth::attempt([
filter_var($identity, FILTER_VALIDATE_EMAIL) ? 'email' : 'username' => $identity,
'password' => $password
]);
}
Your LoginController class should use Trait \Illuminate\Foundation\Auth\AuthenticatesUsers in order to override attemptLogin method i.e.
class LoginController extends Controller {
use \Illuminate\Foundation\Auth\AuthenticatesUsers;
.......
.......
}
I think its even more simple, just override the method from AuthenticatesUsers traits, credentials method in your LoginController. Here I have implemented to login with either email or phone. You can change it to fit your needs.
LoginController.php
protected function credentials(Request $request)
{
if(is_numeric($request->get('email'))){
return ['phone'=>$request->get('email'),'password'=>$request->get('password')];
}
return $request->only($this->username(), 'password');
}
This is the way I do it:
// get value of input from form (email or username in the same input)
$email_or_username = $request->input('email_or_username');
// check if $email_or_username is an email
if(filter_var($email_or_username, FILTER_VALIDATE_EMAIL)) { // user sent his email
// check if user email exists in database
$user_email = User::where('email', '=', $request->input('email_or_username'))->first();
if ($user_email) { // email exists in database
if (Auth::attempt(['email' => $email_or_username, 'password' => $request->input('password')])) {
// success
} else {
// error password
}
} else {
// error: user not found
}
} else { // user sent his username
// check if username exists in database
$username = User::where('name', '=', $request->input('email_or_username'))->first();
if ($username) { // username exists in database
if (Auth::attempt(['name' => $email_or_username, 'password' => $request->input('password')])) {
// success
} else {
// error password
}
} else {
// error: user not found
}
}
I believe there is a shorter way to do that, but for me this works and is easy to understand.
public function username()
{
//return ‘identity’;
$login = request()->input('identity');
$field = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'phone';
request()->merge([$field => $login]);
return $field;
}
protected function validateLogin(Request $request)
{
$messages = [
'identity.required' => 'Email or username cannot be empty',
'email.exists' => 'Email or username already registered',
'phone.exists' => 'Phone No is already registered',
'password.required' => 'Password cannot be empty',
];
$request->validate([
'identity' => 'required|string',
'password' => 'required|string',
'email' => 'string|exists:users',
'phone' => 'numeric|exists:users',
], $messages);
}
https://dev.to/pramanadiputra/laravel-how-to-let-user-login-with-email-or-username-j2h
This solution of "Rabah G" works for me in Laravel 5.2. I modified a litle but is the same
$loginType = request()->input('useroremail');
$this->username = filter_var($loginType, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
request()->merge([$this->username => $loginType]);
return property_exists($this, 'username') ? $this->username : 'email';
Thanks, this is the solution I got thanks to yours.
protected function credentials(Request $request) {
$login = request()->input('email');
// Check whether username or email is being used
$field = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'user_name';
return [
$field => $request->get('email'),
'password' => $request->password,
'verified' => 1
];
}

custom Authentication on Laravel

I want to write a custom authentication on laravel, I want to know should I use default auth or should I write a new?
my auth workflow is:
Step 1- Show email form (in this step we will get just email address)
Step 1-2- check for email existence and if email exists we will go to Step 2 and if not exists I should redirect user to Step 3
Step 2- get the user password (validate password and if everything was OK user will login)
Step 3- show registration form and fill the email with entered user email address (validate form and register user)
What is your solution ?
//Login rules
public function user_login_rules(array $data)
{
$messages = [
'email.required' => 'Please enter your email'
];
$validator = Validator::make($data, [
'email' => 'required'
], $messages);
return $validator;
}
Your post method
public function postSignIn(Request $request)
{
$request_data = $request->all();
$validator = $this->user_login_rules($request_data);
if($validator->fails())
{
return redirect()->back()->withErrors($validator)->withInput();
}
else
{
$email = $request_data['email'];
$user_details = User::where('email', $email)->first();
if(count($user_details) > 0)
{
$credentials = array('email'=> $email ,'password'=> $request_data['password']);
if ($this->auth->attempt($credentials, $request->has('remember')))
{
//Login successful
return redirect()->to('/home');
}
else
{
$error = array('password' => 'Please enter a correct password');
return redirect()->back()->withErrors($error);
}
}
else
{
//Display register page with email
return view('register')->with('email', $email);
}
}
}

Login is Not Working Laravel 5

Hello friends I am using users table column like (USERNAME,EMAIL,PASSWORD)
if i am changing to column name as small letters is working fine. To Change column name as caps is not working give me any suggestion
This is my controller
public function postLogin(Request $request)
{
$this->validate($request, array('username' => 'required', 'password' => 'required'));
$credentials = $request->only('USERNAME', 'PASSWORD');
if (Auth::validate($credentials))
{
$user = Auth::getLastAttempted();
Auth::login($user, $request->has('remember'));
return redirect()->intended($this->redirectPath());
}
return redirect($this->loginPath())
->withInput($request->only('USERNAME', 'remember'))
->withErrors([
'username' => $this->getFailedLoginMessage(),
]);
}
Both user providers that you get with Laravel (EloquentUserProvider and DatabaseUserProvider) expect password to be stored in lowercase password field.
In order to make authentication work with PASSWORD field you need to do 2 things.
First, let providers know that user's password is stored in PASSWORD column. You can do this by implementing getAuthPassword method in your User model:
public function getAuthPassword() {
return $this->PASSWORD;
}
Secondly, password needs to be stored with password key in the credentials array you pass to Auth::validate(). You'll need to change the name of the name of the form field that user inputs password into to password OR create credentials array manually:
$credentials = [
'USERNAME' => $request->get('USERNAME'),
'password' => $request->get('PASSWORD'),
];

Categories