I am doing a simple login and i am facing small problem, just can't figure out what's the problem.
Here is my auth.php :
<?php
return array(
/*
|--------------------------------------------------------------------------
| Default Authentication Driver
|--------------------------------------------------------------------------
|
| This option controls the authentication driver that will be utilized.
| This driver manages the retrieval and authentication of the users
| attempting to get access to protected areas of your application.
|
| Supported: "database", "eloquent"
|
*/
'driver' => 'eloquent',
/*
|--------------------------------------------------------------------------
| Authentication Model
|--------------------------------------------------------------------------
|
| When using the "Eloquent" authentication driver, we need to know which
| Eloquent model should be used to retrieve your users. Of course, it
| is often just the "User" model but you may use whatever you like.
|
*/
'model' => 'Login',
/*
|--------------------------------------------------------------------------
| Authentication Table
|--------------------------------------------------------------------------
|
| When using the "Database" authentication driver, we need to know which
| table should be used to retrieve your users. We have chosen a basic
| default value but you may easily change it to any table you like.
|
*/
'table' => 'tbl_user',
/*
|--------------------------------------------------------------------------
| Password Reminder Settings
|--------------------------------------------------------------------------
|
| Here you may set the settings for password reminders, including a view
| that should be used as your password reminder e-mail. You will also
| be able to set the name of the table that holds the reset tokens.
|
| The "expire" time is the number of minutes that the reminder should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'reminder' => array(
'email' => 'emails.auth.reminder',
'table' => 'password_reminders',
'expire' => 60,
),
);
As you can see above, i am using my own model Login and my own table tbl_user
Below is my model (Login.php)
<?php
class Login extends Eloquent {
protected $table = "tbl_user";
public static function checkUser($array)
{
$data = DB::table('tbl_user')->where('user_email', $array['user_email'])->where('user_password', $array['user_password'])->get();
return $data;
}
}
Now i think there is something wrong with the model, i just don't know what it is. I am moving from CodeIgniter to Laravel 4 and this auth thingy is new for me.
Here is the route :
Route::post('login', function(){
$userdata = array(
'user_email' => Input::get('email'),
'user_password' => Hash::make(input::get('password'))
);
if(Auth::attempt($userdata)){
echo "Login Success!";
}else{
echo "Login Failed!";
}
});
I am getting Login Failed! password is hashed! Hurmm! Any suggestion?
Auth uses a user model which implements the Userinterface, if you want to create your own custom User model you should implement the UserInterface, you can check the deault provided user model in your app:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
/**
* 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');
/**
* 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;
}
}
As Petkostas mentioned, you have to implements UserInterface, RemindableInterface.
In addition, Fix this line as well:
$userdata = array(
'user_email' => Input::get('email'),
'user_password' => Hash::make(input::get('password')) // no need to hash password
);
No need to hash password before Auth::attempt() as Laravel will do it for you.
I have removed Hash::make() from code:
$userdata = array(
'user_email' => Input::get('email'),
'user_password' => input::get('password')
);
if(Auth::attempt($userdata)){
echo "Login Success!";
}else{
echo "Login Failed!";
}
Related
I want to create a Laravel 6 backend with JWT authentication and when I want to sign in a user, JWTAuth always returns false, I google it but can't find any solution for it.
here are my project files codes,
this is my UserController
<?php
namespace App\Http\Controllers;
use App\Http\Requests\UserRequest;
use App\User;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Facades\JWTAuth;
class UserController extends Controller
{
public function signup(Request $request)
{
$user = new User();
$user->name = $request->input('name');
$user->email = $request->input('email');
$user->password = $request->input('password');
$user->save();
return response()->json(['message'=>'User Created Successfully!',$user],201);
}
public function signin(Request $request)
{
$credentials = [];
$credentials['email'] = $request->input('email');
$credentials['password'] = bcrypt($request->input('password'));
try{
if(!$token = JWTAuth::attempt($credentials)){
return response()->json(['error'=>'Invalid Credentials!'],401);
}
}catch(JWTException $e){
return response()->json(['error' => 'Could Not Create Token!'],500);
}
return response()->json(['token'=>$token],200);
}
}
User Model
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* #return mixed
*/
public function getJWTIdentifier() {
return $this->getKey();
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* #return array
*/
public function getJWTCustomClaims() {
return [];
}
public function setPasswordAttribute($password)
{
if ( !empty($password) ) {
$this->attributes['password'] = bcrypt($password);
}
}
}
And Api Route
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::post('/user','UserController#signup');
Route::post('/user/signin','UserController#signin');
when I want to sign in a user, JWTAuth:attempt($credentials), I don't know what I am missing or wrong?
Is there any solution?
I'm a begginer in Symfony 4 and I'm developing an API Rest. I want to create a PUT resource that can handle many update cases.
In my case, I have a user with many properties but I will take an example with 3 properties to keep things simple :
User {
username,
email,
password
}
My PUT resource can be called in order to update Username, update Email or update Password. For example, to update Username, the user of my API will send a PUT request with only username :
{
username: "New username"
}
Same for email and password, he will only send the property he wants to change.
My problem is in my Controller, I have to do things like this :
/**
* #Rest\Put("/user/{id}")
* #param Request $request
* #return View
*/
public function putUserRequest(Request $request)
{
$userId = $request->get('id');
$user = $this->doctrine->getRepository(User::class)->findOneBy('id' => $userId);
$userFromRequest = $this->serializer->deserialize($request->getContent(), User::class, 'json');
if ($userFromRequest->getUsername() != NULL) {
$user->setUsername($userFromRequest->getUsername())
}
if ($userFromRequest->getEmail() != NULL) {
$user->setEmail($userFromRequest->getEmail())
}
if ($userFromRequest->getPassword() != NULL) {
$user->setPassword($userFromRequest->getPassword())
}
// ...
}
In my example I have only 3 properties, but imagine when I have 30 properties.
With Symfony 3 I used forms to validate / save my datas :
$form->submit($request->request->all(), $clearMissing);
Where $clearMissing is false to keep datas not provided by the user of my API. I can't find a way to do it with serializer but I guess I'm doing things wrong.
Thanks.
If I understand correctly, You can use the validator Component like this :
/**
* #Rest\Put("/user/{id}")
* #param Request $request
* #return View
*/
public function putUserRequest(User $user, Request $request, ValidatorInterface $validator)
{
$data = $request->getContent();
$this->serializer->deserialize($data, User::class, 'json', ['object_to_populate' => $user]);
//At this moment, the data you sent is merged with your user entity
/** #var ConstraintViolationList $errors */
$errors = $validator->validate($user, null ,['groups' => 'user_update']);
if (count($errors) > 0) {
//return json reponse with formated errors;
}
//if ok $entityManager->flush() and Response Json with serialization group;
...
}
In your user class :
class User implements UserInterface
{
/**
* #Assert\Email(groups={"user_create", "user_update"})
*/
private $email;
/**
* #Assert\NotBlank(groups={"user_create", "user_update"})
* #Assert\Length(min=7, groups={"user_create", "user_update"})
*/
private $password;
/**
* #Assert\Length(min=2, groups={"user_create", "user_update"} )
*/
private $username;
}
Related Validator component documentation : https://symfony.com/doc/current/validation/groups.html
You can also check this project : https://github.com/attineos/relation-deserializer
I'm using Laravel 5.1 to build back-end system with RESTFUl resources which will be consumed by some mobile applications.
Forgot Password Story
if someone forgot password then the server has to send an email with the temporary password to his registered email. From the next time on words server has to authenticate the user either with temp password or with the password
Can someone guide me how to do this
You can modify your PasswordController located in app\http\controllers\auth
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
use App\Models\User; //yours is probably App\User;
use Mail, Hash;
class PasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Create a new password controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
public function postEmail(Request $request)
{
$this->validate($request, ['email' => 'required|email']);
$email = $request->get('email');
if(!$user = User::where('email', $email)->first()) return redirect()->back()->with('error', 'Email does not exists');
//create temporal password
$temp_password = str_random(8); //generates random 8 characters long string
//hash password and save in database
//I assume you have `temp_password` in your users column
$user->temp_password = Hash::make($temp_password);
$user->save();
//data to be used in mail
$data['subject'] = 'Password Reminder'; //$this->getEmailSubject();
$data['email'] = $email;
$data['temp_password'] = $temp_password;
//send mail to user
Mail::send('emails.password_reminder', $data, function($message) use ($data)
{
$message->from('no-reply#site.com', $data['subject']);
$message->subject($data['subject']);
$message->to($data['email']);
});
}
}
Then in resource/views/emails create password_reminder.blade.php
Your temporal password is {{$temp_password}}
NB:Someone requested a password reminder, if you are not the one kindly ignore
For User Authentication
try - (not tested)
$email = \Request::get('email');
$password = \Request::get('password');
if (Auth::attempt(['email' =>$email, 'password' => $password])){
return true;
}elseif(Auth::attempt(['email' =>$email, 'temp_password' => $password])){
return true;
}else{
return false;
}
or try this
$email = \Request::get('email');
$password = \Request::get('password');
$user = User::where('email',$email)->first();
if(!$user) return false;
if (Auth::attempt(['email' =>$email, 'password' => $password])){
return true;
}elseif(\Hash::check($password, $user->temp_password)){
Auth::loginUsingId($user->id); return true;
}else{
return false;
}
I've got a quite annoying problem at the moment :( hope you can help me out there ...
I'm using the basic login form of laravel at the moment with a pretty much untouched User model.
So, the logging in apparently works (tracked it), but whenever I try to restrict content access (restrict routes) with the help of a middleware, it denies the access.
So, why does it deny me the access if I'm apparently logged in?
I'm really not seeing what I'm doing wrong.
Thanks for your help in advance! (for further information I copied you my middleware, authcontroller and my user model)
<?php namespace App;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'user';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['password', 'remember_token'];
public $timestamps = false;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = ['user_properties_ID', 'email', 'password'];
}
I'm also using the standard AuthController
<?php namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\Registrar;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class AuthController extends Controller {
/*
|--------------------------------------------------------------------------
| Registration & Login Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users, as well as the
| authentication of existing users. By default, this controller uses
| a simple trait to add these behaviors. Why don't you explore it?
|
*/
use AuthenticatesAndRegistersUsers;
/**
* Create a new authentication controller instance.
*
* #param \Illuminate\Contracts\Auth\Guard $auth
* #param \Illuminate\Contracts\Auth\Registrar $registrar
* #return void
*/
public function __construct(Guard $auth, Registrar $registrar)
{
$this->auth = $auth;
$this->registrar = $registrar;
// $this->middleware('guest', ['except' => 'getLogout', 'getLogin']);
}
}
And my middleware looks like this:
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated {
/**
* The Guard implementation.
*
* #var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* #param Guard $auth
* #return void
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if (! $this->auth->check())
{
// return $next($request);
return response('Unauthorized.', 401);
// return redirect()->intended();
// return new RedirectResponse(url('/trainingsplan-hinzufuegen'));
}
return $next($request);
}
}
routes.php
<?php
/*
|--------------------------------------------------------------------------
| Home
|--------------------------------------------------------------------------
*/
Route::group(['prefix' => '', 'middleware' => 'guest', 'namespace' => 'Modules\TrainaryCore\Http\Controllers', 'as' => 'home'], function()
{
Route::get('/home', 'TrainaryCoreController#render');
});
/*
|--------------------------------------------------------------------------
| Registrierung
|--------------------------------------------------------------------------
*/
Route::group(['prefix' => '', 'namespace' => 'Modules\TrainaryCore\Http\Controllers', 'as' => 'registrieren'], function()
{
Route::get('/registrieren', 'TrainaryCoreController#render');
Route::post('/registrieren', 'RegistrationController#validateForm');
});
/*
|--------------------------------------------------------------------------
| Trainingsplan
|--------------------------------------------------------------------------
*/
Route::group(['prefix' => '', 'middleware' => 'guest', 'namespace' => 'Modules\TrainaryCore\Http\Controllers', 'as' => 'schedule'], function()
{
Route::get('/trainingsplan-hinzufuegen', 'TrainaryCoreController#render');
Route::post('/trainingsplan-hinzufuegen', 'ScheduleController#validateForm');
});
Well, what's happening is ok. If you use the GUEST middleware, it'll only allow you in if you are a guest. You gotta use the AUTH middleware.
okay, Laravel uses as a standard 'id' for tables ...
so, if you want to rename it you have to add following to your Model:
protected $primaryKey = 'ID';
that's the solution boys
I am trying to use Laravel's built in authentication, but it is not working. If I hash a password at the registration process, it does not match the hash in the login process, because Laravel's auth generates a totally different hash than Hash:make().
I made a test route and function, to make everything clear
(I tried to use the Auth::attempt() function with Hash::make() and without Hash::make() too, If I pass the Hashed password, it generates a totally different one, If I pass the raw password the Auth doesn't even bother to hash it):
Route::get('/test', function() {
$email = rand(1, 1000) . "test#mail.com";
$password = $email;
$now = new DateTime();
Felhasznalo::create(array(
'teljesnev' => 'valami',
'email' => $email,
'jelszo' => Hash::make($password),
'FelFelhasznaloiSzint_id' => 2,
'created_at' => $now->getTimestamp(),
'aktiv' => 1
));
if (Auth::attempt(array(
'email' => $email,
'jelszo' => Hash:make($password)
))) {
echo 'Working';
} else {
echo 'Not working';
}
});
The first part generates this row to my mysql server:
39test#mail.com, $2y$10$gkzQ2BEuDWN05RQ/OyBH8u4aKRqdL5zSIthUO4BUyEKcscgzRwZzG, valami ....etc
I intentionally mistyped the password field's name to jelszo1 (means password1 in english), when attempting login, to get an sql error.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'jelszo1' in 'where clause' (SQL: select * from `Felhasznalo` where `email` = 39test#mail.com and `jelszo1` = y$XAnnnGNKrOQOxBiX2BnEPOq86Y9mh5h./xwUlfCTPpzW.jzzt3YiO limit 1)
First part (in mysql):
$2y$10$gkzQ2BEuDWN05RQ/OyBH8u4aKRqdL5zSIthUO4BUyEKcscgzRwZzG
Second part (when attempting login):
y$XAnnnGNKrOQOxBiX2BnEPOq86Y9mh5h./xwUlfCTPpzW.jzzt3YiO
and the User model (named as Felhasznalo)
<?php
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class Felhasznalo extends \Eloquent implements UserInterface, RemindableInterface {
use UserTrait,
RemindableTrait;
protected $fillable = [
'id', 'email', 'jelszo', 'teljesnev', 'jelszoreset',
'hash', 'aktiv', 'ban', 'FelFelhasznaloiSzint_id',
'remember_token'
];
protected $guarded = [
];
protected $hidden = [
'jelszo', 'jelszoreset', 'hash'
];
protected $table = 'Felhasznalo';
public $timestamps = true;
protected $softDelete = true;
//----------------------------
//----------------------------
// RELATIONSHIP FUNCTIONS
//----------------------------
//----------------------------
/**
* 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->jelszo;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail() {
return $this->email;
}
public function getRememberToken() {
return $this->remember_token;
}
public function setRememberToken($value) {
$this->remember_token = $value;
}
public function getRememberTokenName() {
return 'remember_token';
}
}
The auth config.:
'model' => 'Felhasznalo',
'table' => 'Felhasznalo',
SQL Error error when using raw password in attempt():
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'jelszo1' in 'where clause' (SQL: select * from `Felhasznalo` where `email` = 832test#mail.com and `jelszo1` = 832test#mail.com limit 1)
The answer to Your question from the post's title (Which Hash function laravel's Auth is using?) can be found on mnshankar.wordpress.com - Laravel Hash::make() explained.
Here is the first sentence from the "How?" section of the linked blog post:
Internally, Hash::make() encrypts using the bcrypt function and Blowfish algorithm.
Also, You can see on the Laravel 5.4 docs - Hashing page that they say:
The Laravel Hash facade provides secure Bcrypt hashing for storing user passwords.
I just checked the Auth code, your password column MUST be called password. You cannot use jelszo
Also - yourr login code is incorrect. You just do this:
if (Auth::attempt(array(
'email' => $email,
'password' => $password
))) {
echo 'Working';
} else {
echo 'Not working';
}
Auth::attempt() will do the hashing for you.