I'm just starting with laravel 5, I'm doing a simple login function to check if email and password passed by user matches with the email and password stored in the database. I've been reading the documentation ([https://laravel.com/docs/5.0/hashing1) but Hash::check($content['password'], $user->{'password'}) returns false always. My code looks like this.
When I create a new user I hash the password like that:
$content = json_decode($request->getContent(), true);
$user -> password = Hash::make($content['email']);
And my login function looks like that:
public function login(Request $request)
{
$content = json_decode($request -> getContent(), true);
$user = DB::table('users')->where('email', $content['email'])->first();
if (Hash::check($content['password'], $user->{'password'}))
{
// Redirect to dashboard
}
}
Thanks in advance!!
Actually you are hashing the email instead of password while creating the user. change the code from
$user->password = Hash::make($content['email']);
To
$user->password = Hash::make($content['password']);
i came up with same issue. check database users table, password field. make the size of the field to 60 or more. this fixed mine.
The facade Hash just will encrypt your data:
Hash::make('123456');
is the same that:
$password = bcrypt('123456');
to login a user you need to use AuthController functions:
Auth::attempt(['email' => 'test#test.com' , 'password' => Hash::make('password')]);
it's a example.
If you're receiving a request, you can add this method to login:
if(Auth::attempt(['email' => $request->email, 'password' => $request->password , 'active' => 1])){
flash()->success('Successfully logged in!');
return redirect('/');
}
the attempt function will hash your password field and will compare with database data.
Related
I want to hash the password after validating the data.
My code:
public function create(Request $request){
$data = Validator::make($request->only(['name', 'email', 'password']), [
'name' => 'required|min:3:max:20',
'email' => 'required|email|unique:users',
'password' => 'required|min:6',
]);
if ($data->fails()) {
//Do something
}else{
User::create($data);
}
}
So how to hash the password after validation?
I tried to override the password inside $data, But it's not working
$data->safe()->only('password') = Hash::make($data->safe()->only('password'));
I can't use $request['password'] as I won't be able to validate it and check if it's empty ..etc.
An alternative approach would be to use an Eloquent Mutator to automatically hash the password field when it is set.
// User Model
public function setPasswordAttribute($value): void
{
$this->attributes['password'] = Hash::make($value);
}
I personally like this approach because you won't have to worry about it in the controllers. You can just set it once and forget about it. :)
The quick answer to your question would be to use the Eloquent make function.
$user = User::make($data);
$user->password = Hash::make($password);
$user->save();
Where $password is where ever you have the password stored. In your case:
$password = $data->safe()->only('password')
There may be a more efficient way, based on your exact intent. In general, the above solution will work.
The make function creates an Eloquent model, but does not store it in the database. That's why you can edit the values and then call $user->save()
Use a mutator method to set the password. Override the method by adding:
public function setPasswordAttribute($value)
{
$this->attributes['password'] = 'some random password generator';
}
there is document:
https://laravel.com/docs/8.x/eloquent-mutators#defining-a-mutator
I want to encrypt password in Laravel.But Hash or Crypt are encryting again again every page refresh. So I dont use it.
$pass = Hash::make($user_password);
$pass = Crypt::encrypt($user_password);
How can i do one times encrypt with Hash or Crypt method ? Because I can't do login page with Hash.
I solved this problem
public function login(Request $request)
{
$email = $request->input('user_email');
$password = $request->input('user_password');
$user = BO_USER::where('email', '=', $email)->first();
if (!$user) {
return response()->json(['success'=>false, 'message' => 'Login Fail, please check email id']);
}
if (!Hash::check($password, $user->password)) {
return response()->json(['success'=>false, 'message' => 'Login Fail, pls check password']);
}
//return response()->json(['success'=>true,'message'=>'success', 'data' => $user]);
return redirect('/dashboard');
}
You will use the Hash, cause Crypt can be decrypted.
See documentation:
Hashing for password
Encrypt and decrypt values
I want to make the password optional while login into the system. If the user enters the password the login works fine and return the jwt token, when I entered to try to login only with email it gives the following error:-
Undefined index: password (500 Internal Server Error)
The following is the code of my login method
public function authenticateUser($request)
{
$input = $request->only('email','password');
if (!$authorized = Auth::attempt($input, true)) {
return $this->failure('Credentials doesnot match our records!', 401);
} else {
$token = $this->respondWithToken($authorized);
return $this->success('Login Successfully !', $token, 200);
}
}
protected function respondWithToken($token)
{
return [
'token' => $token,
'token_type' => 'Bearer',
'expires_in' => Auth::factory()->getTTL() * 60,
'user' => Auth::user()
];
}
so basically, what I want is when a user enters an email it will login and should return the token, and if the user login with email and password then it should also work and return the token.
You can create a custom Authentication User Provider that will work around this potentially missing 'password' field. Though, I would probably not here. You can check the input yourself to see if there is a password or not. If there is pass it through attempt like normal. If it is not there find the user using the configured User Provider and login to the guard (what attempt is doing).
Perhaps something like this:
public function authenticateUser($request)
{
if ($request->has('password')) {
$token = Auth::attempt($request->only(['email', 'password']));
} else {
$token = ($user = Auth::getProvider()->retrieveByCredentials($request->only(['email'])))
? Auth::login($user)
: false;
}
return $token
? $this->success('Login Successfully !', $this->respondWithToken($token), 200)
: $this->failure('Credentials do not match our records!', 401);
}
The error that you're getting means that there is no password key in the input array that you're sending via request. This happens on this line:
$input = $request->only('email','password');
In order to bypass that, you would need go get all inputs, or check if those inputs exist and then read from them:
//Get all inputs
$input = $request->input();
//Or get email first, and then check for password
$input['email'] = $request->email;
$input['password'] = $request->filled('password') ? $request->password : null;
Note: Since I can't see your actual login functions, this might not work with only email, since password might be required parameter. If that's the case, you will have to alter those functions.
I would like to pass / submit the user_id of the currently logged on user. How will I do it in laravel 5.2? Please need help
I am not sure on my code on how will I use Auth:user() blah blah. Need help with this. I am new to this.
You can use the login functionality like this and pass the datas to the required pages as per your wish.
public function Dologin()
{
// create our user data for the authentication
$userdata = array(
'email' => Input::get('email'),
'password' => Input::get('password'),
);
if (Auth::attempt($userdata))
{
$user_id=Auth::user()->user_id;// user_id it will change as per the users table in your project.
return redirect('index');
}
else
{
}
}
Make sure you save your password using bcrypt method and for that alone the Auth::check() and Auth::user() will work.
auth()->id() will provide the user id
It is possible to create user from Admin panel, by administrator without password? I imagine follow procedure:
Administrator create user without password
User get email with instruction for entering password and activation account
User can register with email and his password
I don't think so. That's why when I create my users I generate a random password.
$user->password = str_shuffle("Random_Password"); // generate random initial password
I have done this before by hacking the 'forgotten password' functionality of Laravel (rather that reinventing the wheel). I can't say how well this fits into Sentry but it was pretty trivial to do it in plain old Laravel:
Create user with blank password
Add an entry into the password reminders table (manually, don't use Auth::remind or whatever it is as it'll send an email, but do use the code from the class to generate the token)
Send welcome email to user with link to /user/confirm (or whatever, the point is that it doesn't have to be /user/forgotten-password) and hook that route up in the normal way for forgotten password with an added check for $user->password == '' if you wanna make sure only unconfirmed people can go to that page (not that it really matters).
You may also wish to extend the timeout on the forgotten passwords or, as I did (proper hacky I know), when the user's in the /user/confirm version of the forgotten password functionality, just refresh the timeout in the table before passing through to Laravel's auth system for checking.
Our code is something like this:
On register:
// however you register the user:
$user = new User;
$user->email = Input::get('email');
$user->password = '';
$user->save();
// create a reminder entry for the user
$reminderRepo = App::make('auth.reminder.repository');
$reminderRepo->create($user);
Mail::send(
'emails.registered',
[
'token' => $reminder->token,
],
function ($message) use ($user) {
$message->to($user->email)->setSubject(Lang::get('account.email.registered.subject', ['name' => $user->name]));
}
);
Now the confirm link:
class AccountController extends Controller
{
public function confirm($token)
{
$reminder = DB::table('password_reminders')->whereToken($token)->first();
if (! $reminder) {
App::abort(404);
}
// reset reminder date to now to keep it fresh
DB::table('password_reminders')->whereToken($token)->update(['created_at' => Carbon\Carbon::now()]);
// send token to view but also email so they don't have to type it in (with password reminders it's is a good thing to make users type it, but with confirm account it feels weird)
return View::make('account.confirm-account')->withToken($token)->withEmail($reminder->email);
}
public function postConfirm($token)
{
$credentials = Input::only('email', 'password', 'password_confirmation', 'token');
$response = Password::reset($credentials, function ($user, $password) {
$user->password = $password;
$user->save();
});
switch ($response) {
case Password::INVALID_PASSWORD:
case Password::INVALID_TOKEN:
case Password::INVALID_USER:
return Redirect::back()->withInput()->with('message-error', Lang::get($response));
case Password::PASSWORD_RESET:
Auth::login(User::whereEmail(Input::get('email'))->first());
return Redirect::route('account.home')->with('message-info', Lang::get('messages.confirm_account.succeeded'));
}
}