It is not authing right after registiration with laravel Auth class - php

Everything is ok unless authing in this code. That returns "false". This is my first try with this class I'm already beginner for laravel. I don't know that is really basic problem but I can not see the problem, that's why I ask this.
public function signupDone(){
$rules = array(
'username' => 'required|unique:users|min:5', // Minumum 5 Characters and Unique
'password' => 'required|min:8', // Password must be 8 characters, at least
'password2' => 'same:password', // Password2 must be same of password
'email' => 'required|email|unique:users' // Email must be an e-mail adress unique
);
$validation_result = Validator::make(Input::all(), $rules);
if($validation_result->fails()){
return Redirect::to('signup')->withErrors($validation_result);
}
$user = new Users;
$user->username = Input::get('username');
$user->password = Hash::make(Input::get('password'));
$user->email = Input::get('email');
if($user->save()){
if(Auth::attempt(array("username"=>$user->username, "password"=>Input::get('password')))){
return Redirect::to('/');
}
else{
return "false";
}
}
Thanks.
EDIT:
/config/auth.php
<?php
return array(
'driver' => 'eloquent',
'model' => 'Users',
'table' => 'users',
'reminder' => array(
'email' => 'emails.auth.reminder',
'table' => 'password_reminders',
'expire' => 60,
),
);
And users table:
Users Model:
<?php
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class Users 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');
}

As #user3158900 noticed correctly, your password column needs to be 60 characters long, otherwise the hash will be truncated become useless.
Still there's no need to use Auth::attempt if you know the users credentials are valid (because he just created his account).
In such cases you can just use Auth::login
if($user->save()){
Auth::login($user);
return Redirect::to('/');
}
There's no need to check if the login worked because:
You are not validating credentials
If anything drastically goes wrong an exception will be thrown
If the user for some reason doesn't get logged in without error there's still your auth filter that will redirect to a login form (I suppose)

Yes I have to change the password field to 60 varchar. But I've just noticed that, Auth::attempt returns false if username and password ok.
if (Auth::attempt(array('email' => $email, 'password' => $password)))
{
return Redirect::intended('dashboard');
}

Related

No hashing on Password field in Laravel seeder

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')
]);
}

cakephp would not hash password while login but only in signup

I am using CakePHP 3.5. I am trying to create a simple login but I have problems:
I can login with the password that has not been hashed
My defaultpasswordhasher works... the password is actually being hashed but while login it doesn't
all users (user1, user2, user3) have same password "password"
user1 password is not hashed
UserController.php
public function login(){
if($this->request->is('post')){
// $data = $this->request->getData();
//pr($data);
$user = $this->Auth->identify();
if($user){
$this->Flash->success('Successful login');
$this->Auth->setUser($user);
return $this->redirect(['action' => 'index']);
}else{
$this->Flash->error(__('Please, try again.'));
}
}
}
<?php
namespace App\Model\Entity;
use Cake\Auth\DefaultPasswordHasher;
use Cake\ORM\Entity;
/**
* UsersTable Entity
*
* #property int $id
* #property string $username
* #property string $email
* #property string $password
*/
class UsersTable extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* #var array
*/
protected $_accessible = [
'username' => true,
'email' => true,
'password' => true
];
/**
* Fields that are excluded from JSON versions of the entity.
*
* #var array
*/
protected $_hidden = [
'password'
];
protected function _setPassword($password){
return(new DefaultPasswordHasher)->hash($password);
}
}
login.ctp
<?= $this->Form->create();?>
<?= $this->Form->control('email'); ?>
<?= $this->Form->control('password'); ?>
<?= $this->Form->button('login');?>
<?= $this->Form->end(); ?>
AppController.php
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler', [
'enableBeforeRedirect' => false,
]);
$this->loadComponent('Flash');
$this->loadComponent('Auth',[
'authenticate' =>[
'Form' => [
'fields' => [
'username' =>'email',
'password' =>'password'
]
]
],
'loginAction' => [
'controller' =>'UsersTable',
'action' =>'login'
]
]);
https://book.cakephp.org/3.0/en/controllers/components/authentication.html
_setPassword function only works when you add or edit an entity in your table.
Since you added user1 before adding _setPassword in the User Entity that why it was not hashed.
Also it doesn't hash the user1 when you login as nothing changes in the User Entity in the table.
If you want to hash user1, just edit it form the admin panel.

User passes Auth::attempt(); Fails Auth::check('user')

I'm working with an old copy of a client's database and making the new Laravel app work with its existing users.
I was building and testing with my User model using the 'users' table, but I'm trying to hook it up to the 'auth_user' table. After the changes, my new users are being created correctly. The login is a problem though. The users are passing Auth::attempt($credentials) as expected, but failing when
In my LoginController...
// post to /login
public function login() {
$input = Request::all();
// Log the user in
if (Auth::attempt(['email'=>$input['username'], 'password'=>$input['password']])) {//Auth::attempt(Auth::attempt("admin", ['email' => $input['username'], 'password' => $input['password'], 'active' => 1])) {
// the user is now authenticated.
return Redirect::to('/welcome')->with('message', 'Successfully authenticated');
}
return Redirect::to('/')
->with('message', 'Login Failed: Your Login Credentials Are Invalid');
}
}
I'm definitely passing the Auth::attempt(...), but I don't think my session is being set for that user. After the redirect to /welcome, I fail the Auth::check('user')
public function welcome() {
if (!Auth::check('user')) return Redirect::to('/');
// ... Top secret stuff (no returns or redirects though)
return view('user.welcome', [
'user' => Auth::user()
// ...
]);
}
This redirects back to my login controller.
The kicker is this was all working when I was using my 'users' table instead of 'auth_user'.
Users uses id as the primary key, Auth_user uses 'uid' as the primary key. I'd love to change the uid to be id, but I have to reuse a scary number of MYSQL stored procedures that I can't change.
Relevant models:
User.php:
class User extends Model implements AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword;
public function rules($scenario = null, $id = null) {
$rules = [];
switch($scenario) {
case 'userAdd':
$rules = [
'password' => 'required|confirmed|min:6'
];
break;
case 'passwordChange':
$rules = [
'password' => 'required|confirmed|min:6'
];
break;
}
return $rules;
}
public function isValid($scenario = null) {
$validation = User::make($this->attributes, User::rules($scenario));
if($validation->passes()) return true;
$this->errors = $validation->messages();
return false;
}
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'auth_user';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['username', 'name', 'password', 'email', 'expire', 'active', 'organization','role'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['password', 'remember_token'];
protected $primaryKey = 'uid';
}
Auth.php (for multiple user types -- I know, I'd rather use roles instead of separate models too)
<?php
return [
'multi' => [
'user' => [
'driver' => 'eloquent',
'model' => App\User::class,
'table' => 'auth_user'
],
'admin' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
'table' => 'auth_admin'
]
],
];
I think I covered all my bases for the primary key change, but I can't get the model to pass Auth::check(). Can someone with more Laravel experience illuminate what I'm doing wrong? Thanks in advance!
This is not a complete fix. I still can't find anything to tell Laravel/Guard not to look at the ID column, so I bandaided it by adding an ID column and $user->id = $user->uid;. I'm not proud of this, but it works.
In your User.php Script you need to place this code and this code make the table to login check.
protected $table='auth_users';
In your User.php code place that protected table code in initial stage( after the class function).

Laravel get id of latest inserted user

I'm using the Laravel Auth to make users able to register. What I'm now trying is: After users register (if they have a special role selected), there is another row inserted into another table (then users) which holds the relating user id. This is the code for it:
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
use App\Complaint;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after login / registration.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
'username' => 'required|unique:users',
'role' => 'required'
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
$user = new User;
$user->name = $data['name'];
$user->email = $data['email'];
$user->username = $data['username'];
$user->password = bcrypt($data['password']);
$user->role = $data['role'];
$user->templateURL = "";
/*$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'username' => $data['username'],
'password' => bcrypt($data['password']),
'role' => $data['role'],
'templateURL' => ""
]);*/
$user->save();
if($data['role'] == 'Verkäufer'){
$complaintRow = Complaint::create([
'user_id' => $user->id,
'complaintCount' => 0
]);
}
switch($data['role']){
case 'Käufer':
$user->attachRole(2);
break;
case 'Verkäufer':
$user->attachRole(3);
break;
default:
$user->attachRole(2);
break;
}
return $user;
}
}
But it's not working correctly, the user is inserted as well as a row for the complaints, but somehow $user->id seems to be null, the column always has user_id set to 0. Any ideas why this could be like this?
EDIT: I got it working now... It was actually not the code I posted, I just didn't make the user_id field fillable in the complaint table, that's why there was 0 in always, because 0 was the default value, so it just didn't set it.
Thanks all for the answers anyway.
As per Laravel Eloquent ORM, $user->id will return the Id of user.
If you are getting null, then there might be error in saving. (https://stackoverflow.com/a/21084888/6628079)
Try printing $user after saving it.
UPDATE:
It would be better if you add data in complaint table if user is saved successfully.
protected function create(array $data)
{
$user = new User;
$user->name = $data['name'];
$user->email = $data['email'];
$user->username = $data['username'];
$user->password = bcrypt($data['password']);
$user->role = $data['role'];
$user->templateURL = "";
/*$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'username' => $data['username'],
'password' => bcrypt($data['password']),
'role' => $data['role'],
'templateURL' => ""
]);*/
if ($user->save()) {
if ($data['role'] == 'Verkäufer') {
$complaintRow = Complaint::create([
'user_id' => $user->id,
'complaintCount' => 0
]);
}
switch ($data['role']) {
case 'Käufer':
$user->attachRole(2);
break;
case 'Verkäufer':
$user->attachRole(3);
break;
default:
$user->attachRole(2);
break;
}
return $user;
} else {
// Your code if user doesn't save successfully.
}
}
This is because, Eloquent save method bool but not the instance of newly created Entity. For confirmation checkout this link: https://laravel.com/api/5.3/Illuminate/Database/Eloquent/Model.html
So, if you want to get the newly created instance you can either user create method or make another query to get newly inserted instance. First one is better ans easy. Here is how you can do it:
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'username' => $data['username'],
'password' => bcrypt($data['password']),
'role' => $data['role'],
'templateURL' => ""
]);
Now, you have $user variable containing User instance. But to do this you need to consider fillable/guared issue in your model. I mean, in your model you have to add the following line:
protected $fillabe = ['name', 'email', 'username', 'password', 'role', 'templateURL']
Is column id exists?
Try to set $primaryKey = 'id' on model (user).
After $user->save you can access to id like $user->id
Or after $user->save try to get max id from your table.
$user = User::select('id')->max('id')->first();
Try this:
$lastId = User::create($userData)->id;
$user->id will tell you created user's ID right after using save() method.
You did all most correct you just need to change,
when you are saving user object it will return saved user object so just grab that object and use in furcher conditions.
$saved_user = $user->save();
if(!empty($saved_user)){
if($data['role'] == 'Verkäufer')
{
$complaintRow = Complaint::create([
'user_id' => $saved_user->id,
'complaintCount' => 0
]);
}
} else {
throw new error(500);
}
Hope this will help thanks :)

How to sign in an active user in Laravel 5.2?

I have a users table which holds every detail of the user including a field called 'isActive' which is a Boolean.
I want to log in the user if the 'isActive = 1' and also i want to redirect the user back to the login page if the 'isActive = 0'.
My code is below:
public function postSignIn(Request $request)
{
$this->validate($request, [
'username' => 'required',
'password' => 'required'
]);
if(Auth::attempt(['username' => $request['username'], 'password' => $request['password']])) {
return redirect()->route('home');
}
}
The code above allows me to sign normally. With or without the isActive field being called.
As per Documentation,
If you wish, you also may add extra conditions to the authentication
query in addition to the user's e-mail OR username and password. For
example, we may verify that user is marked as "active":
In your case, you just need to add 'isActive' => 1 in array.
Your code should be:-
if (Auth::attempt(['username' => $request['username'], 'password' => $request['password'],'isActive' => 1])) {
// The user is active, not suspended, and exists.
}
else{
// The user is Inactive, suspended, or not exists.
return redirect()->route('home');
}
Simply add the extra field into the attempt method
if(Auth::attempt([
'username' => $request['username'],
'password' => $request['password'],
'isActive' => 1,
])
)
{
return redirect()->route('home');
}
This is all covered in the documentation.
I don't know where you guys are getting your code from as mine is massively different. Are you guys upgrading to 5.2 or installing it through a fresh install of 5.2? Here's what I have in my login method:
if (Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {
return $this->handleUserWasAuthenticated($request, $throttles);
}
I didn't want to override the remember functionality, so I use this way:
/**
* Get the needed authorization credentials from the request.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
protected function getCredentials(Request $request)
{
$request = $request->only($this->loginUsername(), 'password');
$request['active'] = true;
return $request;
}
Basically add $request['active'] = true; to the getCredential method in your App/Http/Controllers/Auth/AuthController and Bob's your uncle.

Categories