i need a two way Login. First check database one if user exists and if not check database two.
So i build a custom Login Controller:
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Facades\Redirect;
use App\Http\Controllers\Controller;
class CustomLoginController extends Controller
{
public function login(Request $request)
{
if($request->email) {
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// Authentication passed...
return redirect()->intended('/');
} else {
DB::setDefaultConnection('otherdb');
if (Auth::attempt($credentials)) {
// The Login credentials will be found and user will be logged in
but after Redirect to home user isn't logged in anymore.
return redirect()->intended('/');
} else {
return redirect()->to('/login')
->withInput($request->only($credentials['email'], 'remember'))
->withErrors([
'email' => Lang::get('auth.failed'),
]);
}
}
} else {
return view('auth.login');
}
}
}
After i changed the database Connection with "DB::setDefaultConnection('otherdb');", the second login works but after Redirect to any page user isn't logged in anymore.
What am I doing wrong?
Any ideas?
Laravel trying to find a user in DB in every request. So after redirect there in no user in your default database. DB connection doesn't stored in session.
I think you need to create a custom auth guard with another user model like
class OtherUser extends Eloquent
{
protected $connection = 'otherdb';
}
and work with it.
Related
How to set email and password to admin login using guards??
If I have to login for the 1st time in admin login portal what email and password is it going to verify with.
I tried adding record to database directly and logging in but that doesn't work.
when i try to login with email and password in the database, i get the following error
Argument 1 passed to Illuminate\Auth\EloquentUserProvider::validateCredentials() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of App\Models\Admin given, called in C:\xampp\htdocs\Alumni datatable - Copy (2) - Copy\vendor\laravel\framework\src\Illuminate\Auth\SessionGuard.php on line 434
AdminAuthController
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Session;
class AdminAuthController extends Controller
{
public function getLogin(){
return view('admin.auth.login');
}
public function postLogin(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required',
]);
if(auth()->guard('admin')->attempt(['email' => $request->input('email'), 'password' => $request->input('password')])){
$user = auth()->guard('admin')->user();
if($user->is_admin == 1){
return redirect()->route('adminDashboard')->with('success','You are Logged in sucessfully.');
}
}else {
return back()->with('error','Whoops! invalid email and password.');
}
}
public function adminLogout(Request $request)
{
auth()->guard('admin')->logout();
Session::flush();
Session::put('success', 'You are logout sucessfully');
return redirect(route('adminLogin'));
}
}
you have to extends Authenticatable in your Admin Model
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
}
I am trying to create a custom verification flow, where as soon as a user clicks the verification link, it logs him in and also verifies him, instead of first making him log in and only then the verification link works.
I built a custom notification URL in my CustomVerificationNotification, including the registered user_id, to login him later:
protected function verificationUrl($notifiable)
{
if (static::$createUrlCallback) {
return call_user_func(static::$createUrlCallback, $notifiable);
}
return URL::temporarySignedRoute(
'verification.custom-verify',
Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)),
[
'id' => $notifiable->getKey(),
'hash' => sha1($notifiable->getEmailForVerification()),
'user_id' => $this->user->id
]
);
}
Then in my web.php I added this route:
Route::get('/email/verify/{id}/{hash}/{user_id}','Auth\CustomVerifyController#login_and_verify')->name('verification.custom-verify');
Then in my CustomVerifyController:
public function login_and_verify(EmailVerificationRequest $request)
{
//..
}
But I get Call to a member function getKey() on null. And I can't edit EmailVerificationRequest, so what can I do? Is it possible to somehow call Auth::login($user); before calling the EmailVerificationRequest? (Because I have the user_id from the route)
I tried to follow the best answer from this post as well: How to Verify Email Without Asking the User to Login to Laravel
But I'm not sure then how to trigger the verify() method from the web.php and send the $request when I'm first calling the verify_and_login method
First you need verify that the URL is signed by adding the middleware signed
You don't want that anoyone having the url /email/verify/{id}/{hash}/{user_id} able to access this ressource without the signature.
web.php
Route::get('/email/verify/{id}/{hash}/{user_id}','Auth\CustomVerifyController#login_and_verify')
->middleware('signed')
->name('verification.custom-verify');
Then you need to verify that the hash correspond the user_id and for that you can use a Request or a Middleware. I think the Request fits better since Laravel already uses a Request for this.
CustomEmailVerificationRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Auth\Events\Verified;
use Illuminate\Foundation\Http\FormRequest;
class EmailVerificationRequest extends FormRequest
{
public function authorize()
{
$user = User::findOrFail($this->route('id'));
if (! hash_equals((string) $this->route('hash'), sha1($user->getEmailForVerification()))) {
return false;
}
return true;
}
}
Finally you need to login with the user and set is email as verified
CustomVerifyController.php
public function login_and_verify(CustomEmailVerificationRequest $request)
{
$user = User::findOrFail($this->route('id'));
Auth::login($user);
$user->markEmailAsVerified();
event(new Verified($user));
...
}
[Edit to add addition feature from comments]
In order to have a middleware that verify the signed URL and resend automatically the verification email, you need to build a custom middleware.
ValidateSignatureAndResendEmailVerification.php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Routing\Exceptions\InvalidSignatureException;
use URL;
class ValidateSignatureAndResendEmailVerification
{
public function handle($request, Closure $next, $relative = null)
{
if(! URL::hasCorrectSignature($request, $relative !== 'relative')( {
throw new InvalidSignatureException;
}
if (URL::signatureHasNotExpired()) {
return $next($request);
}
return redirect()->route('resend-email-confirmation');
}
}
Then you need to add the middleware to Kernel.php
Kernel.php
protected $routeMiddleware = [
...
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'signed.email' => \App\Http\Middleware\ValidateSignatureAndResendEmailVerification::class,
...
];
Then, don't forget to update your route with the new middleware
web.php
Route::get('/email/verify/{id}/{hash}/{user_id}','Auth\CustomVerifyController#login_and_verify')
->middleware('signed.email')
->name('verification.custom-verify');
I want to manually login a user in laravel 8. The problem is that authentication succeeds, but the authenticated user is not stored in the session(or the session is not updated). I use the method given in de docs.
My loginController has two methods: 1) showing the login form and 2) performing the login
<?php
namespace App\Http\Controllers;
use App\Http\Requests\LoginRequest;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
public function login(){
return view('auth/login');
}
public function validateLogin(LoginRequest $request){
if (Auth::attempt(['email'=>$request->email, 'password'=>$request->password])) {
$request->session()->regenerate();
return redirect()->to('/');
}
return back()->withErrors(['credentials' => 'Deze gegevens zijn niet bekend!']);
}
}
The controller redirects indeed to / , so the user is authenticated but after the redirect the autenticated users is unavailable, so somehow it is not stored in the session.
Does anyone know how to solve this?
I removed the id from the User model as I wanted to use the e-mailadress as the primary key. This violated the Authenticable trait so the session was not updated.
The usermodel needed the following function to replace the id with the email:
public function getKeyName(){
return 'email';
}
The same can be accomplished with:
protected $primaryKey = 'email';
public $incrementing = false;
I used laravel like 4 years ago. Had to work on a project on laravel and tried using my own authentication methods but mybad forgot there was already inbuilt better security authentication. I understand if my question seem to be basic.
As you can see the commented line "$userID = Auth::user()->userID;" the auth() is null therefore, userID cannot get its id from null. I am unable to get user session data in any other controllers as well.
Any kind of help or suggestions is appreciated.
P.S. i have used the default login and registration inbuilt function only required function like login is override code. I am using laravel v 4.2.3. I tried passing the userid as url parameter but then discarded it as inbuilt session data makes it more secure and easier
the login function of my controller looks like this
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = RouteServiceProvider::HOME;
public function __construct()
{
$this->middleware('guest')->except('logout');
}
protected function login(Request $request){
$user = new User(); //my model User
$result=$user->login($request); //result has the id of the user
if ($result) {
//$userID = Auth::user()->userID;
return redirect()->route('homepage');
}else{
return redirect()->route('login');
}
}
}
model for user login()
//Auth user then let them login
public function login($request){
$email = $request->input('email');
$password = $request->input('password');
$result=DB::table('users')
->where('email', $email)
->where('password', $password)
->get();
return $result;
}
My Routes.. its default route of "Auth::routes();"
Route::get('/homepage/{userID?}', function($userID = null){
return view('index', ['userID' => $userID]);
})->name('homepage');
Route::get('/evaluate/{userID?}', function ($userID = null) {
return view('evaluate', ['userID' => $userID]);
})->name('evaluate');
I installed a fresh new laravel and tried my code again and somehow it worked. Must have made some errors when trying to override the codes. Thank you
I'm trying to manually auth my user like this :
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use Auth;
use Log;
use Hash;
class UsersController extends Controller
{
public function authenticate(Request $request){
$email = $request->input('email');
$password = $request->input('password');
if (Auth::attempt(['email' => $email, 'password' => $password])) {
// Authentication passed...
return response()->json(User::find($email));
}
return response()->json(null);
}
}
I verify my request data, my database data, all is ok. I've also done a Hash::check with my user password and my request password, all is ok.
But the attempt always returning false.
Thanks !
Finally, I found it.
This was because I was attending a result but
return response()->json(User::find($email));
didn't find a user. So I change it for the following
return response()->json(User::where('email', $email)->first());
Thanks !