add in conditional to Laravel auth - php

In my users table I have role field which can be filled with any of admin, driver, petugas, rental. I want to let the user with role either admin or rental login, other than that the login system will deny the user.
I try to override the credentials() method in LoginController.php like below
protected function credentials(Request $request)
{
$field = $this->field($request);
return [
$field => $request->get($this->username()),
'password' => $request->get('password'),
'role'=>['admin', 'jasa_angkutan', 'rental']
];
}
but it's not working.. I truely have no idea how to achieve the requirement.

here's a dirty hack but at least works in my case.
protected function credentials(Request $request)
{
$field = $this->field($request);
$user = \App\User::where([
$field=>$request->get($this->username())
])->whereIn('role', [
'admin', 'jasa_angkutan', 'rental'
])->first();
if($user){
return [
$field => $request->get($this->username()),
'password' => $request->get('password')
];
}
return [];
}
before pass the credentials to auth method, I, first check if the user and role match the criteria. that's it.

Related

Laravel Redirection and logic queue with email verification

I have one form in frontend where I have there is some city details , rooms details and user registration in one form like I have city name , room name , address etc email addresss and password in same form and I have done 2 logics in one controller for creating cities and registering user
It is saving the both data in correct table in the database
but I want that first user should register and if user is vcerified only the room details should be saved in database
I am in confusion wheather to apply if again or what
public function checkLogin(Request $request)
{
$user = User::create([
'name'=>$request->name,
'email'=>$request->email,
'password'=>$request->password,
'role_id' => config('quickadmin.default_role_id'),
]);
if ($user) {
if (Auth::check()) {
$city = TotalCity::create([
'name'=>$request->name,
'created_by'=>$request->created_by_id,
]);
}
return redirect()->to('/admin/home');
}
}
Let me show you how I'd probably write this logic:
public function checkLogin(Request $request)
{
$user = User::firstOrCreate([
'email'=> $request->email,
],
[
'name'=> $request->name,
'password'=> bcrypt($request->password),
'role_id' => config('quickadmin.default_role_id'),
]);
if (Auth::check()) {
// it's not clear if you utilize `email_verified_at`, if so
// if (Auth::check() && Auth::user()->email_verified_at) {
$city = TotalCity::create([
'name'=>$request->name,
'created_by'=> Auth::user()->id, // or $user->id depending on your preference
]);
}
return redirect('/admin/home');
}
The firstOrCreate() checks if an entry with that email exists, it gets it, otherwise creates it.
Furthermore, if I want to check for Authentication, I'd use 'auth' middleware in my route.
Route::get('example', 'ExampleController#checkLogin')->middleware('auth');
That removes the need of entire check:
if (Auth::check()) { ... }

Login a user only if his status is active in Laravel 5.7

I am new to Laravel and have been fairly successful in implementing user authentication. Now to move on to the next step I must allow only users whose status in active to login. For that I have added a
status TINYINT
column in my mysql users table.
I found this in the Laravel Documentation:
Specifying Additional Conditions
If you wish, you may also add extra conditions to the authentication
query in addition to the user's e-mail and password. For example, we
may verify that user is marked as "active":
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// The user is active, not suspended, and exists.
}
Can someone please point out where I need to put this chunk. Am thoroughly confused and need some pointers.
Thanks
Have this on your LoginController:
protected function credentials(Request $request)
{
return ['username' => $request->{$this->username()}, 'password' => $request->password, 'status' => 1];
}
You just take user status and check user status is true or false. You can take status using Auth::User()->status from auth session. Try this.
if(Auth::attempt(['email'=>$request->email,'password'=>$request->password])){
$userStatus = Auth::User()->status;
if($userStatus=='1') {
return redirect()->intended(url('/dashboard'));
}else{
Auth::logout();
Session::flush();
return redirect(url('login'))->withInput()->with('errorMsg','You are temporary blocked. please contact to admin');
}
}
else {
return redirect(url('login'))->withInput()->with('errorMsg','Incorrect username or password. Please try again.');
}
Just simply put this code in your App\Auth\LoginController or elsewhere where you have your LoginController located.
public function authenticate(Request $request)
{
$credentials = $request->only('email', 'password');
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// Authentication passed...
return redirect()->intended('dashboard');
}
}
with this code you are overriding default authenticate function
Add this to your LoginController:
protected function credentials(Request $request)
{
return [$this->username() => $request->{$this->username()}, 'password' => $request->password, 'active' => 1];
}
Add below method in
app\Http\Controllers\Auth\LoginController.php
and it would extend
AuthenticatesUsers trait
validateLogin method. So basically, it would check for your active clause as well.
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => [
'required',
Rule::exists('users')->where(function ($query) {
$query->where('active', 1);
}),
],
'password' => 'required'
]);
}
OR
Place your required code in app\Http\Controllers\Auth\LoginController.php
public function authenticate(Request $request)
{
if (Auth::attempt(['email' => $request->email, 'password' => $request->password, 'active' => 1])) {
// The user is active, not suspended, and exists.
}
}
You can override authenticated() method in your App\Http\Controllers\Auth\LoginController.php like so:
protected function authenticated(Request $request, $user)
{
if(!$user->active) {
Auth::logout();
abort(403);
};
}
Do note it's quick but not very "Laravely" solution. Sloppy.

Laravel- Creating new user only if there is data in another table

I have two tables the first one is the user table which have these property id, username, email,remember_token, createdat, updateat another table is called received_pay having id, email, token my task is to check if the email, and token entered by the user must match the ones in received_pay otherwise new user is not created, thanks for your time in advanced,
I'm trying to create new user on a condition that if there is data in another table then new user is created otherwise not I have put my code inside if else statement and is throwing errors.
my function for creating new user is listed below:
protected function create(array $data)
{
/*$exists = \DB::table('received_pay')->where('email', $data['email'])->first(); */
$exists=\DB::table('received_pay')->where('email', '=', $data['email'])->where('token', $data['token'])->exists();
if ($exists === null)
{
// user doesn't exist
return User::create([
'username' => $data['username'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'token' => $data['token'],
]);
}
else
{
return null;
}
}
I think that the best approach in Laravel is create a middleware to protect this url. If you already have this create user feature working is better don't modify it.
So the first step would be create a middleware (https://laravel.com/docs/5.5/middleware) to add your safeguard, something like this:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckPayment
{
public function handle($request, Closure $next)
{
$payment = \DB::table('received_pay')->where('email', $request->email)->where('token', $request->token]);
if (!$payment->count()) {
return redirect('no-payment');
}
return $next($request);
}
}
Then you would need to create a route to handle this invalid creation users (this no-payment url).
And finally you can protect your create-user url in route, by adding your middleware in your kernel.php file...
protected $routeMiddleware = [
...
'payment' => \App\Http\Middleware\CheckPayment::class,
];
and in your web.php route file:
Route::post('user', 'UserController#create')->middleware('payment');
In this way your code will look cleaner, tidier, and closer to the way Laravel works.
I hope it would work fine for you.
If you wish to do it with if statement then do it like below
protected function create(array $data)
{
/*$exists = \DB::table('received_pay')->where('email', $data['email'])->first(); */
$exists=\DB::table('received_pay')->where('email', '=', $data['email'])->where('token', $data['token']);
if (!$exists->count())
{
// user doesn't exist
return User::create([
'username' => $data['username'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'token' => $data['token'],
]);
}
else
{
return null;
}
}
the count() in the if is to make the statement evaluate true if the data exists and false otherwise and create the new user.
I think that solves your problem.

How can I login the user manually in Laravel?

Here is my code:
public function register_and_login(Request $request)
{
$this->validator_short($request->all())->validate();
$user = User::where('cell_phone', $request->cell_phone)->first();
// already registered
if ( is_null($user) ) {
$user_id = User::create([
'name' => $request->name,
'cell_phone' => $request->cell_phone,
'password' => bcrypt($request->password),
]);
} else {
$user_id = $user->id;
}
$this->guard()->login($user_id);
dd('user is logged in now');
}
My code works when the user isn't registered so far and we create it. But when he has registered already, my code throws this error:
How can I fix it?
Make sure the User model extends Authenticatable:
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
Also, use auth() helper or Auth:: facade:
$user = User::create(['name' => $request->name,
'cell_phone' => $request->cell_phone,
'password' => bcrypt($request->password)
]);
auth()->login($user);
https://laravel.com/docs/5.5/authentication#other-authentication-methods
Change your else part to -
else {
$user_id = $user;
}
The login function is not asking you for an integer id, it's asking for an Authenticable. In any default Laravel application, that's usually the User Model.
The problem lies in your else statement. You don't need to set $user_id to the id of the user you loaded when checking the cell number. You just need to use the user you loaded. Based on your logic, you don't even need the else statement.
A possible separate issue with your logic,is that you're checking to see if the cell number exists, and if it does, logging in that user, not the user that your doing the check for. This may be desired behaviour, but it doesn't seem like.
public function register_and_login(Request $request)
{
$this->validator_short($request->all())->validate();
$user = User::where('cell_phone', $request->cell_phone)->first();
// already registered
if ( is_null($user) ) {
$user = User::create([
'name' => $request->name,
'cell_phone' => $request->cell_phone,
'password' => bcrypt($request->password),
]);
}
$this->guard()->login($user);
}

Login is Not Working Laravel 5

Hello friends I am using users table column like (USERNAME,EMAIL,PASSWORD)
if i am changing to column name as small letters is working fine. To Change column name as caps is not working give me any suggestion
This is my controller
public function postLogin(Request $request)
{
$this->validate($request, array('username' => 'required', 'password' => 'required'));
$credentials = $request->only('USERNAME', 'PASSWORD');
if (Auth::validate($credentials))
{
$user = Auth::getLastAttempted();
Auth::login($user, $request->has('remember'));
return redirect()->intended($this->redirectPath());
}
return redirect($this->loginPath())
->withInput($request->only('USERNAME', 'remember'))
->withErrors([
'username' => $this->getFailedLoginMessage(),
]);
}
Both user providers that you get with Laravel (EloquentUserProvider and DatabaseUserProvider) expect password to be stored in lowercase password field.
In order to make authentication work with PASSWORD field you need to do 2 things.
First, let providers know that user's password is stored in PASSWORD column. You can do this by implementing getAuthPassword method in your User model:
public function getAuthPassword() {
return $this->PASSWORD;
}
Secondly, password needs to be stored with password key in the credentials array you pass to Auth::validate(). You'll need to change the name of the name of the form field that user inputs password into to password OR create credentials array manually:
$credentials = [
'USERNAME' => $request->get('USERNAME'),
'password' => $request->get('PASSWORD'),
];

Categories