I'm trying to do a basic authentication which considers email and password. My problem comes when I call the method Auth :: attempt I get the following error.
Model
class Usuario extends Eloquent{
protected $table = 'Usuario';
protected $primaryKey = 'idUsuario';
protected $fillable = array('Nombre',
'Apellido',
'TipoUsuario',
'Contrasena',
'Correo',
'Telefono');
}
Controller
class UsuarioController extends BaseController{
public function doLogin(){
$rules = array('correo' => 'required|email',
'contrasena' => 'required');
$validator = Validator::make(Input::all(), $rules);
if($validator->fails()){
return Redirect::to('usuario')
->withErrors($validator)// manda los errores al login
->withInput(Input::except('contrasena')); //
}else{
$userData = array(
'Correo' => Input::get('correo'),
'Contrasena' => Input::get('contrasena')
);
if(Auth::attempt($userData)){
echo 'bien';
}else{
return Redirect::to('login');
}
}
}
public function showLogin(){
return View::make('login');
}
}
Routte
Route::get('usuario', array('uses' => 'UsuarioController#showLogin'));
Route::post('usuario', array('uses' => 'UsuarioController#doLogin'));
Auth.php
return array(
'driver' => 'database',
'model' => 'User',
'table' => 'Usuario',
'reminder' => array(
'email' => 'emails.auth.reminder',
'table' => 'password_reminders',
'expire' => 60,
),
);
In the process of checking user credentials Laravel calls validateCredentials method when Auth::attempt gets called and in this function (given below) Laravel checks for the password key in the passed array and in your case you are not passing a password key so the error happens.
public function validateCredentials(UserInterface $user, array $credentials)
{
$plain = $credentials['password'];
return $this->hasher->check($plain, $user->getAuthPassword());
}
Change the key in the $userData array:
$userData = array(
'email' => Input::get('correo'), // If correo means email
'password' => Input::get('contrasena') // If contrasena means password
);
Also make changes in your database table's field names which represents users table, I think it's your Usuario table.
I'd check to make sure you're passing the correct info to Auth::attempt() in your controller. I use something more like:
$userData = array('email' => Input::get('email'), 'password' => Input::get('password'));
Related
So my test case in laravel is the following:
public function test_user_can_sign_up_using_the_sign_up_form()
{
$user = User::factory()->create();
$user = [
'username' => $user->username,
'email' => $user->email,
'password' => $user->password,
'password_confirmation' => $user->password,
'dob' => $user->dob
];
$response = $this->post('/register', $user);
// Removes password confirmation from array
array_splice($user, 3);
$this->assertDatabaseHas('users', $user);
$response->assertRedirect('/home');
}
This line:
$response->assertRedirect('/home');
is causing the test to fail and get an output of 'The email has already been taken' Why is this the case? I want to check upon sign up, the user is directed to the home page which it does but my test fails.
The user is being created in the database so that part works fine.
UserFactory:
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
/**
* #extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class UserFactory extends Factory
{
/**
* Define the model's default state.
*
* #return array<string, mixed>
*/
public function definition()
{
return [
'username' => fake()->name(),
'email' => fake()->unique()->safeEmail(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'dob' => fake()->date(),
];
}
/**
* Indicate that the model's email address should be unverified.
*
* #return static
*/
public function unverified()
{
return $this->state(fn (array $attributes) => [
'email_verified_at' => null,
]);
}
}
Okay I will explain your test case to you.
You are testing a register feature of your app.
$user = User::factory()->create();
$user = [
'username' => $user->username,
'email' => $user->email,
'password' => $user->password,
'password_confirmation' => $user->password,
'dob' => $user->dob
];
$response = $this->post('/register', $user);
this block of code is wrong because you are using the data of a User already inside the database to create an account. So it will naturally fails since the data is already inside the database the moment you call the User::factory()->create().
So instead of that you should pass a data that looks like you are the one registering.Remove the User::factory()->create() then replace the array $user with hard coded data or use the fake() helper.
$user = [
'username' => fake()->userName(),
'email' => fake()->unique()->safeEmail(),
'password' => 'password',
'password_confirmation' => 'password',
'dob' => 'asldkjasd'
];
$response = $this->post('/register', $user);
$response->assertValid();
$this->assertDatabaseHas('users', [
'email' => $user['email'],
]);
$response->assertRedirect('/home');
I have a unit acceptance test where I am mocking the creation of a user.
class UserAcceptanceApiTest extends TestCase
{
use WithoutMiddleware;
public function setUp()
{
parent::setUp();
$this->User = factory(App\Models\User::class)->make([
'id' => '999',
'name' => 'Name',
'email' => 'test#example.com',
'password' => bcrypt('password'),
]);
$this->User = factory(App\Models\User::class)->make([
'id' => '999',
'name' => 'Name',
'email' => 'test#example.com',
'password' => bcrypt('password'),
]);
$user = factory(App\Models\User::class)->make();
$this->actor = $this->actingAs($user);
}
public function testStore()
{
$response = $this->actor->call('POST', 'api/users', $this->User->toArray());
$this->assertEquals(200, $response->getStatusCode());
$this->seeJson(['id' => 999]);
}
}
I get the following exception "Field 'password' doesn't have a default value.
This is because in my User model I have the following:
protected $hidden = ['password', 'remember_token'];
So it automatically removes the password field from the JSON.
Is there a way I can override this only for this test? As I want to keep the password as a hidden attribute.
public function testStore()
{
$this->User->makeVisible(['password']);
$response = $this->actor->call('POST', 'api/users', $this->User->toArray());
$this->assertEquals(200, $response->getStatusCode());
$this->seeJson(['id' => 999]);
}
I have viewed a lot off documents already. I am trying to do my login, but its not working. Showing errors. I don't know the reason.i am very new in laravel
This is my controller code
public function do_login()
{
$credentials = [
'username'=>Input::get('username'),
'password'=>Input::get('password')
];
$rules = [
'username' => 'required',
'password'=>'required'
];
//validating the credentials.
$validator = Validator::make($credentials,$rules);
//in case the credentials are valid. Try to login the user.
if($validator->passes())
{
if (Auth::attempt($credentials))
{
//if successfull redirect the user
return Redirect::to('home');
}
else
{
//else send back the login failure message.
return Redirect::back()->withInput()->with('failure','username or password is invalid!');
}
}
else
{
//send back the validation errors.
return Redirect::back()->withErrors($validator)->withInput();
}
}
this is my model code:
<?php namespace LARAVEL\laravel_1st_project\models\UserModel;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class UserModel extends \Eloquent implements UserInterface , RemindableInterface
{
public $table = "user";
protected $primaryKey = 'employee_id';
//public $timestamps = false;
}
this is my app\config\auth.php :
'model' => 'LARAVEL\laravel_1st_project\UserModel',
'table' => 'user',
'reminder' => array(
'email' => 'email.auth.reminder',
'table' => 'password_reminders',
'expire' => 60,
),
Error :
I really try to debug my issues on my own before I bring them here, but I seriously cannot find a solution to my laravel auth problem, though it seems to be a common issue.
My authentication will not login. It always returns false and I don't understand why.
I've read through some other questions here, and their solutions haven't solved my particular situation.
My User model implements UserInterface and Remindable Interface.
My password is hashed upon creating it to the database.
My password field in my database is varchar 100, which should be more than enough to hash the password.
The user I'm logging is has been created and activated in the database.
Thank you so much for any insight.
User Model
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
protected $fillable = array('email', 'username', 'password', 'password_temp', 'code', 'active');
public $timestamps = false;
protected $softDelete = false;
/**
* 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 = 'password';
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
}
Account Controller
class AccountController extends BaseController {
public function getLogin() {
return View::make('account.login');
}
public function postLogin() {
$validator = Validator::make(Input::all(),
array(
'email' => 'required',
'password' => 'required'
)
);
if($validator->fails()) {
return Redirect::route('login')
->withErrors($validator);
} else {
$auth = Auth::attempt(array(
'email' => Input::get('email'),
'password' => Input::get('password'),
'active' => 1
));
if($auth) {
return Redirect::route('Create-Account');
}
}
return Redirect::route('login')
->with('global', 'There was a problem logging you in. Please check your credentials and try again.');
}
public function getCreate() {
return View::make('account.create');
}
public function getviewReturn() {
return View::make('account.return');
}
public function postCreate() {
$validator = Validator::make(Input::all(),
array(
'email' => 'required|max:50|email|unique:Users',
'username' => 'required|max:15|min:4|unique:Users',
'password' => 'required|min:6',
'password2' => 'required|same:password'
)
);
if ($validator->fails()) {
return Redirect::route('Post-Create-Account')
->withErrors($validator)
->withInput();
}
else {
$email = Input::get('email');
$username = Input::get('username');
$password = Input::get('email');
$code = str_random(60);
$user = User::create(array(
'email' => $email,
'username' => $username,
'password' => Hash::make($password),
'code' => $code,
'active' => 0));
});
return Redirect::to('account/return')
Routes
Route::group(array('before' => 'guest'), function() {
Route::group(array('before' => 'csrf'), function() {
Route::post('/account/create', array(
'as' => 'Post-Create-Account',
'uses' => 'AccountController#postCreate'
));
Route::post('/account/login', array(
'as' => 'postlogin',
'uses' => 'AccountController#postLogin'
));
});
Route::get('/account/login', array(
'as' => 'login',
'uses' => 'AccountController#getLogin'
));
Route::get('/account/create', array(
'as' => 'Create-Account',
'uses' => 'AccountController#getCreate'
));
Route::get('/account/activate/{code}', array(
'as' => 'Activate-Account',
'uses' => 'AccountController#getActivate'
When creating the user you've done
$password = Input::get('email');
It should be
$password = Input::get('password');
so if you try and login with the "email" as the password - it will work! :)
So if you change this
else {
$email = Input::get('email');
$username = Input::get('username');
$password = Input::get('email');
$code = str_random(60);
$user = User::create(array(
'email' => $email,
'username' => $username,
'password' => Hash::make($password),
'code' => $code,
'active' => 0));
});
to this
else {
$user = User::create(array(
'email' => Input::get('email'),
'username' => Input::get('username'),
'password' => Hash::make(Input::get('password');),
'code' => str_random(60),
'active' => 0));
});
that cleans up your code and fixes the issue.
Your code looks right to me, so you have to check some things:
1) A manual attempt works for you?
dd( Auth::attempt(['email' => 'youremail', 'password' => 'passw0rt']) );
2) The user hash checks manually?
$user = User::find(1);
var_dump( Hash::check($user->password, 'passw0rt') );
dd( Hash::check($user->password, Input::get('password')) );
Try to add primaryKey field in your user model. It should be something like that:
protected $primaryKey = 'user_id';
I think Apache version problem. You need to update Apache2.4.
I'm trying the Laravel's Auth class but the method returns false always. Here's my code:
Controller :
public function postLogin()
{
// Declare the rules for the form validation.
//
$rules = array(
'email' => 'Required|Email',
'password' => 'Required'
);
// Get all the inputs.
//
$email = Input::get('email');
$password = Input::get('password');
// Validate the inputs.
//
$validator = Validator::make(Input::all(), $rules);
// Check if the form validates with success.
//
if ($validator->passes())
{
//echo $password; displays test
// Try to log the user in.
//
if (Auth::attempt(array('email' => $email, 'password' => $password)))
{
// Redirect to the users page.
//
return Redirect::to('account')->with('success', 'You have logged in successfully');
}
else
{
// Redirect to the login page.
//
return Redirect::to('account/login')->with('error', 'Email/password invalid.');
}
}
// Something went wrong.
//
return Redirect::to('account/login')->withErrors($validator->getMessageBag());
}
Seeder.php
public function run()
{
DB::table('users')->delete();
$users = array(
array(
'email' => 'test#test.com',
'password' => Hash::make('test'),
'first_name' => 'John',
'last_name' => 'Doe',
'created_at' => new DateTime,
'updated_at' => new DateTime,
)
);
DB::table('users')->insert( $users );
}
It will be because of framework bug. So try to update it.
composer update
Or
php composer.phar update
In your config/auth.php file
try changing from 'driver' => 'eloquent' to 'driver' => 'database'.