Laravel Auth::attempt failing each time - php

I have created a test user on my laravel app. The details are
user: joe#gmail.com pass: 123456
When I go through the registration process everything works as expected and an entry is made into the users table of the database
Once this is finished I redirect the user to the dashboard.
public function postCreate(){
//Rules
$rules = array(
'fname'=>'required|alpha|min:2',
'lname'=>'required|alpha|min:2',
'email'=>'required|email|unique:users',
'password'=>'required|alpha_num|between:6,12|confirmed',
'password_confirmation'=>'required|alpha_num|between:6,12'
);
$validator = Validator::make(Input::all(), $rules);
if($validator->passes()){
//Save in DB - Success
$user = new User;
$user->fname = Input::get('fname'); //Get the details of form
$user->lname = Input::get('lname');
$user->email = Input::get('email');
$user->password = Hash::make(Input::get('password'));//Encrypt the password
$user->save();
return Redirect::to('/books')->with('Thank you for Registering!');
}else{
//Display error - Failed
return Redirect::to('/')->with('message', 'The Following Errors occurred')->withErrors($validator)->withInput();
}
}
I then navigate back to the landing page and attempt to log in using the credentials above and I keep getting told that Auth::attempt() is failing hence my user cannot log into the application.
public function login(){
if(Auth::attempt(array('email'=>Input::get('email'), 'password'=>Input::get('password')))){
//Login Success
echo "Success"; die();
return Redirect::to('/books');
}else{
//Login failed
echo "Fail"; die();
return Redirect::to('/')->with('message', 'Your username/password combination was incorrect')->withInput();
}
}
Does anyone know why this is happening? This is the Schema for my users table:
Schema::create('users', function($table){
$table->increments('id');
$table->integer('type')->unsigned();
$table->string('fname', 255);
$table->string('lname', 255);
$table->string('email')->unique();
$table->string('password', 60);
$table->string('school', 255);
$table->string('address_1', 255);
$table->string('address_2', 255);
$table->string('address_3', 255);
$table->string('address_4', 255);
$table->string('remember_token', 100);
$table->timestamps();
});
Any help is much appreciated.
'View for Login':
<div class="page-header">
<h1>Home page</h1>
</div>
<!-- Register Form -->
<form action="{{ action('UsersController#postCreate') }}" method="post" role="form">
<h2 class="form-signup-heading">Register</h2>
<!-- Display Errors -->
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
<!-- First Name -->
<div class="form-group">
<label>First Name</label>
<input type="text" class="form-control" name="fname" />
</div>
<!-- Last Name -->
<div class="form-group">
<label>Last Name</label>
<input type="text" class="form-control" name="lname" />
</div>
<!-- Email -->
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" name="email" />
</div>
<!-- Password-->
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="password" />
</div>
<!-- Confirm Password -->
<div class="form-group">
<label>Confirm Password</label>
<input type="password" class="form-control" name="password_confirmation" />
</div>
<input type="submit" value="Register" class="btn btn-primary"/>
</form>
<!-- Login Form -->
<form action="{{ action('UsersController#login') }}" method="post" role="form">
<h2 class="form-signup-heading">Login</h2>
<!-- Email -->
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" name="email" />
</div>
<!-- Password-->
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="password" />
</div>
<input type="submit" value="Login" class="btn btn-primary"/>
</form>

Can you run this function below - and tell me where the error occurs? It will diagnose the problem:
public function testLogin()
{
$user = new User;
$user->fname = 'joe';
$user->lname = 'joe';
$user->email = 'joe#gmail.com';
$user->password = Hash::make('123456');
if ( ! ($user->save()))
{
dd('user is not being saved to database properly - this is the problem');
}
if ( ! (Hash::check('123456', Hash::make('123456'))))
{
dd('hashing of password is not working correctly - this is the problem');
}
if ( ! (Auth::attempt(array('email' => 'joe#gmail.com', 'password' => '123456'))))
{
dd('storage of user password is not working correctly - this is the problem');
}
else
{
dd('everything is working when the correct data is supplied - so the problem is related to your forms and the data being passed to the function');
}
}
Edit: one thought - are you sure the user is being correctly saved in the database? Have you tried to 'empty/delete' your database and try your code again? In your current code, it will fail if you keep registering with joe#gmail.com - because it is unique. But you dont catch the error anywhere. So empty the database and try again...
Edit 2: I found another question you posted with the same problem - and in there you mentioned that the following code is your user model?
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password');
public function getAuthIdentifier() {
}
public function getAuthPassword() {
}
public function getRememberToken() {
}
public function getRememberTokenName() {
}
public function getReminderEmail() {
}
public function setRememberToken($value) {
}
}
Is that EXACTLY your current user model? Because if so - it is wrong - none of those functions should be blank.
This is what a CORRECT user model should look like for Laravel 4.2
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
}

You would make sure about:
your model:
mine looks like:
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
protected $table = 'users';
protected $hidden = array('password');
public function getAuthIdentifier()
{
Return $this->getKey ();
}
public function getAuthPassword()
{
return $this->password;
}
}
make sure your app/config/auth.php is configured correctly
make sure app/config/app.php has service provider
'Illuminate\Auth\AuthServiceProvider',
Make sure your controller class has auth. before writing class you have used Auth (I mean include Auth class)
That all could make Auth doesn't work well

With password hashing enabled, the User model must override these methods:
public function getAuthIdentifierName()
{
return 'email';
}
public function getAuthIdentifier()
{
return request()->get('email');
}
public function getAuthPassword()
{
return Hash::make(request()->get('password'));
}

What is the value for strlen(Hash::make(Input::get('password')))? If it is greater than 60, then this would cause the authentication to fail each time, as the stored password is not the full hash.

Good day, here is what I discovered when I encountered the same error: A simple string compare will reveal that the two hashing methods produce two different hashed values.
echo strcmp(Hash::make('password'),bcrypt('password'));
My assumption is that Auth::attempt([]) uses bcrypt() to hash out passwords which produces a different value to what you used Hash:make().

Related

Laravel Error to inicialice ValidationFactory

I'm making my login system, through the LoginController controller, which in turn calls a request called loginRequest [I still have to update some names to Pascal]
My request only has two rules that username and password are required.
Then in a function getCredentials() I capture the username of this and validate that it is an email or not, this to give the user the option to log in both ways.
To identify if the user is actually an email, create a method 'isMail' in which I establish $factory with the content validated through an alias set to Validacion\Factory , ValidationFactory, but when executing the submit button it throws me the error :
Target [Illuminate\contracts\Validation\Factory] is not instantiable.
Could you help me?
template [login.blade.php]:
#extends('components\header')
<section class="vh-100">
<div class="container-fluid h-custom">
<div class="row d-flex justify-content-center align-items-center h-100">
<div class="col-4">
<img src="{{ URL::asset('img/logo.png') }}"
class="img-fluid" height="500">
</div>
<div class="col-md-8 col-lg-6 col-xl-4 offset-xl-1">
<form action="{{route('samein.login')}}" method="POST">
#csrf
<!-- Email input -->
<div class="form-outline mb-4">
<input type="text" name="username" class="form-control form-control-lg"
placeholder="Usuario" />
<label class="form-label" for="form3Example3">Usuario</label>
</div>
<!-- Password input -->
<div class="form-outline mb-3">
<input type="password" name="password" class="form-control form-control-lg"
placeholder="Contraseña" />
<label class="form-label" for="form3Example4">Contraseña</label>
</div>
<div class="text-rigth text-lg-start mt-4 pt-2">
<button type="submit" class="btn btn-primary btn-lg"
style="padding-left: 2.5rem; padding-right: 2.5rem;">Iniciar Sesión</button>
</div>
</form>
</div>
</div>
</div>
</section>
controller[LoginController.login]
<?php
namespace App\Http\Controllers;
use App\Http\Requests\loginrequest;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use Illuminate\Queue\RedisQueue;
class LoginController extends Controller
{
public function index(){
return view('login');
}
public function login( loginrequest $request ){
$credentiales = $request->getCredentials();
if( Auth::validate($credentiales) ){
return redirect()->to('login')->withErrors('auth.failed');
}
$user = Auth::getProvider()->retrieveByCredentials($credentiales);
Auth::login($user);
return $this->authenticated($request,$user);
}
public function authenticated (Request $request,$user){
return redirect('accountModule.indexusers');
}
}
and my Request[loginrequst.php]
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\contracts\Validation\Factory as ValidationFactory;
class loginrequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array<string, mixed>
*/
public function rules()
{
return [
//
'username'=>'required',
'password'=>'required'
];
}
public function getCredentials(){
$username = $this->get('username');
if( $this->isMail($username) ){
return['email'=> $username,
'password' => $this->get('password')
];
}
return $this->only('username','password');
}
public function isMail($value){
$factory = $this->container->make(ValidationFactory::class);
return !$factory->make(['username'=>$value],['username'=>'email'])->fails();
}
}
I was reading your problem and I found interesting the way you plan to check if the email is there or not.
I know it doesn't answer your question but you could try the following:
In your Request:
public function rules()
{
return [
//
'username'=>'required',
'password'=>'required'
];
}
In your controller:
public function login( loginrequest $request ){
$field = filter_var($request->input('username'), FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
$request->merge([$field => $request->input('username')]);
//validate credentials
if (!Auth::validate($request->only($field, 'password'))) {
return redirect()->to('login')->withErrors('auth.failed');
}
//create a session
$user = Auth::getProvider()->retrieveByCredentials($request->only($field, 'password'));
Auth::login($user);
return redirect()->to('/');
}
don't forget to configure your web.php file, so that the routes work for you. I hope I've helped.

Single Validation in Laravel

I am very new to Laravel, and our system uses multiple forms within a single page to insert the single bitcoin wallet into each input field, but as it stands the user is able to use it on all inputs and this is wrong as could i make only one valid? such as "username" "email" etc ..
html:
<form method="POST" action="/wallet3-edit/update">
<div class="form-group hidden">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="_method" value="PATCH">
</div>
<div class="form-group {{ $errors->has('bitzpayer_id3') ? ' has-error' : '' }}">
<label for="bitzpayer_id3" class="control-label"><b>Wallet:</b></label>
<input type="text" name="bitzpayer_id3" placeholder="Please enter your Wallet here" class="form-control" value="{{ $user->bitzpayer_id3 }}"/>
<?php if ($errors->has('bitzpayer_id3')) :?>
<span class="help-block">
<strong>{{$errors->first('bitzpayer_id3')}}</strong>
</span>
<?php endif;?>
</div>
<div class="form-group">
<button type="submit" class="btn btn-warning text-white"> Submit </button>
</div>
</form>
Controller:
<?php
namespace App\Http\Controllers;
use Auth;
use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class Wallet3Controller extends Controller
{
/**
* Update user profile & make backend push to DB
*
**/
public function index() {
/**
* fetching the user model
**/
$user = Auth::user();
//var_dump($user);
/**
* Passing the user data to profile view
*/
return view('/wallet3-edit', compact('user'));
}
public function update(Request $request) {
/**
* fetching the user model
*/
$user = Auth::user();
/**
* Validate request/input
**/
$this->validate($request, [
'bitzpayer_id3' => 'max:255|unique:users,bitzpayer_id3,'.$user->id,
]);
/**
* storing the input fields name & email in variable $input
* type array
**/
$input = $request->only('bitzpayer_id3');
/**
* Accessing the update method and passing in $input array of data
**/
$user->update($input);
/**
* after everything is done return them pack to /profile/ uri
**/
return back();
}
}
Routes:
Route::get('wallet3-edit', 'Wallet3Controller#index');
Route::patch('wallet3-edit/{id}', 'Wallet3Controller#update');
if you want to validate not duplication in a single page:
because The page dosent send any request to server until the form completes,
you can check this within javascript/jquery like this:
$(".inputs").change(function(){
if($("#input1").val()==$("#input2").val()){
$("#input1").addClass("error");
}
});
but if your input are seprated in different pages and save in database you can validate with them with this kind of rules in Laravel controller or Laravel Request Class:
$validationRules = ["wallet" => "required|unique:wallets_table,btc"];
where "wallet" is the name of your input field. "wallets_table" is your database table and "btc" is table column.
but if you are not willing to save the wallet public keys in Database and the requests are from a single user, you can save the "Address"es in a Session Array and check them out when a user submit a request. but this solution works User Scope .
please give me more details if I misunderstood.

Laravel 5.4 Authentication

Im trying to create login form and its controller but when i try to login it doesnt work can any one help me i'm very new in laravel.
here is my form
<form action="/login" method="post">
{{ csrf_field() }}
<div class="form-group has-feedback">
<input type="email" name="email" class="form-control" placeholder="Email">
<span class="glyphicon glyphicon-envelope form-control-feedback"></span>
</div>
<div class="form-group has-feedback">
<input type="password" name="password" class="form-control" placeholder="Password">
<span class="glyphicon glyphicon-lock form-control-feedback"></span>
</div>
<div class="row">
<div class="col-xs-7">
<div class="checkbox">
<label>
<input type="checkbox"> Remember Me
</label>
</div>
</div>
<!-- /.col -->
<div class="col-xs-5">
<button type="submit" class="btn btn-primary btn-raised btn-block ">Sign In</button>
</div>
<!-- /.col -->
</div>
</form>
and here is my route
Route::get('/login', 'loginController#create');
Route::post('/login', 'loginController#store');
and my loginController is
class loginController extends Controller
{
public function __construct(){
$this->middleware('guest', ['except' => 'destroy']);
}
public function create(){
return view('pages.admin.login');
}
public function store(){
if(! auth()->attempt(request(['email', 'password']))){
return back()->withErrors([
'message' => 'Please check your credentials'
]);
}
return redirect('/home');
}
}
My user modal is
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'fname','oname','lname', 'email', 'phone','password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
Please where i'm i doing wrong on these, when i entered email and password as my credential it just refresh and back to login page
auth()->attempt() requires an array, you're sending the return value of request() as a single argument, may that be it?
Your function should be like this with Request facade.
public function store(Request $request){
if(! auth()->attempt($request->only(['email', 'password']))){
return back()->withErrors([
'message' => 'Please check your credentials'
]);
}
return redirect('/home');
}
Here is how your attempt function should be like:
if(Auth::attempt( ['email'=> $request['email'],'password' => $request['password'] ])
Add these on top of LoginController
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
and modify your store method
public function store(Request $request){
$email = $request->email;
$password = $request->password;
if (! Auth::attempt(['email' => $email, 'password' => $password])) {
// Authentication Failed...
return back()->withErrors([
'message' => 'Please check your credentials'
]);
}
return redirect('/home');
}
Also remove password from $hidden in your User Model.
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'remember_token',
];
Hope it's helpful.
You can use php artisan make:auth and laravel will produce everything needed for a login including the controller and then you can go into your resource and edit to make it look how you imagined.
This is what my login controller looks like after using php artisan make:auth
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}

validate unique username from a different model

in a form i'm working on, it will check if username was empty on registration and prompt to input a username before a user ads a comment.
i tired adding unique in my rules in my comment class, but it doesn't validate on ajax post
class Comment extends CActiveRecord
{
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
return array(
array('username', 'unique','className'=>'User','attributeName'=>'username','message'=>"Username already exists"),
);
}
in my view
echo '<div class="form-group">
'.$form->labelEx($user,'username', array('class'=>'col-md-3 control-label')).'
<div class="col-md-9">
'.$form->textField($user,'username',array('class'=>'form-control input-md')).'
'.$form->error($user,'username').'
</div>
</div>';
//the output looks like this
/*<label class="col-md-3 control-label" for="User_username">Username</label>
<div class="col-md-9">
<input class="form-control input-md" name="User[username]" id="User_username" type="text" value="" />
<div class="errorMessage" id="User_username_em_" style="display:none"></div>
</div>*/
in my controller
public function actionCreate()
{
/** #var Comment $comment */
$comment = Yii::createComponent($this->module->commentModelClass);
// Uncomment the following line if AJAX validation is needed
$a=new User;
$b=new Comment;
$this->performAjaxValidation(array($a,$b));
//end of Ajax validation
.....
.....
.....
}
/**
* Performs the AJAX validation.
* #param CModel the model to be validated
*/
protected function performAjaxValidation($model)
{
if(isset($_POST['ajax']) && $_POST['ajax']==='ext-comment-form')
{
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
the return Json is
{"Comment_username":["Nick Name cannot be blank."],"Comment_title":["Review Title cannot be blank."]}
any idea what i'm doing wrong?
problem solved.
had to add
array('username', 'unique'),
in my User class and NOT in my comment class

it's not validating my form data

i have form like this
my form
<?php
$error = $model->getErrors();
print_r($error);
<form method="post" action="<?php echo Yii::app()->getBaseUrl(true).'/index.php/admin/user/resetpassword'?>" enctype="multipart/form-data">
<div class="row">
<label>Old Password</label><input type="password" name="oldpassword" value="<?php echo $model->email; ?>"/><span><?php if(isset($error['email'])) echo $error['email'][0]; ?></span>
</div>
<div class="row">
<label>New Password</label><input type="password" name="newpassword"/><span><?php if(isset($error['password'])) echo $error['password'][0]; ?></span>
</div>
<div class="row">
<label>Repeat Password</label><input type="password" name="repeatpassword" value="<?php echo $model->employeeid; ?>"/><span><?php if(isset($error['employeeid'])) echo $error['employeeid'][0]; ?></span>
</div>
<?php echo CHtml::submitButton($model->isNewRecord ? 'Reset Password' : 'Save'); ?>
</form>
my model class is
class User extends CActiveRecord
{
public $oldpassword;
public $newpassword;
public $repeatpassword;
/**
* #return string the associated database table name
*/
public function tableName()
{
return 'user';
}
/**
* #return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('email, password, employeeid, designation, manager, profilepic', 'required','except'=>'resetpassword'),
array('email','email'), array('profilepic','file','types'=>'jpg,jpeg,png','allowEmpty'=>true,'on'=>'update'),
array('email,employeeid','unique'),
array('newpassword, repeatpassword, oldpassword','required','on'=>'resetpassword'),
array('repeatpassword','compare','compareAttribute'=>'newpassword','on'=>'resetpassword'),
array('email, password, employeeid, designation, manager, profilepic', 'safe', 'on'=>'search'),
);
}
my controller function
public function actionResetPassword()
{
$model = new User('resetpassword');
if(Yii::app()->request->isPostRequest)
{
if($model->validate())
$this->redirect(array('resetpassword','msg'=>'Password successfully changed..'));
}
$this->render('resetpassword',array('model'=>$model));
}
it always giving error say "oldpassword,repeatpassword,newpassword required" even though have entered value..
can anybody help me pls
Thanks in advance
it's because you are not assigning form value to model variable...
try this in your controller
if(Yii::app()->request->isPostRequest)
{
$model->oldpassword=$_POST['oldpassword']; //will set to model variable
$model->newpassword=$_POST['newpassword'];
$model->repeatpassword=$_POST['repeatpassword'];
if($model->validate())
$this->redirect(array('resetpassword','msg'=>'Password successfully changed..'));
}
hope it may solve your problem
As mentioned by Kalpit above, you are not assigning form inputs to your model instance.
You may also solve this problem like this..
$model = new User;
if(isset($_POST['resetpassword']))
{
$model->attributes=$_POST['resetpassword'];
if($model->save())
// successfully saved, do something here
}

Categories