I am working on 2FA via email in my application , the problem I am facing is whenever I am logging in it automatically gets logged out and send me back to login page although it is sending me an email with correct user email through which I tried to login and it do not reaches to verify page .
here is my login_submit function
public function login_submit(Request $request)
{
if(Auth::check()){
return redirect()->route('admin.home')->with('success','Successfully logged in');
}
$request->validate([
'email' => 'required|email',
'password' => 'required|min:5',
]);
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// if(Auth::user()->role->name == 'Customer'){
// return redirect()->route('home')->with('success','Successfully logged in');
// }
$user = auth()->user();
$user->generateTwoFactorCode();
$user->notify(new TwoFactorCode());
if(auth()->check()) {
return redirect()->route('verify.index')->with('success','Successfully logged in');
}
}else{
return back()->with('error','These credentials do not match with our record');
}
}
My User modal which includes both generate code and reset methods
<?php
namespace App;
use IlluminateContractsAuthMustVerifyEmail;
use IlluminateFoundationAuthUser as Authenticatable;
use IlluminateNotificationsNotifiable;
use IlluminateDatabaseEloquentSoftDeletes;
use AppReview;
class User extends Authenticatable
{
use Notifiable;
public $table = 'users';
protected $dates = [
'updated_at',
'created_at',
'deleted_at',
'email_verified_at',
'two_factor_expires_at',
];
protected $guarded = [];
/**
* 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',
];
/**
* Generate 6 digits 2FA code for the User
*/
public function generateTwoFactorCode()
{
$this->timestamps = false; //Dont update the 'updated_at' field yet
$this->two_factor_code = rand(100000, 999999);
$this->two_factor_expires_at = now()->addMinutes(10);
$this->save();
}
/**
* Reset the 2FA code generated earlier
*/
public function resetTwoFactorCode()
{
$this->timestamps = false; //Dont update the 'updated_at' field yet
$this->two_factor_code = null;
$this->two_factor_expires_at = null;
$this->save();
}
}
Here is my verify routes along with middleware
Route::get('verify/resend', 'AuthTwoFactorController@resend')->name('verify.resend');
Route::resource('verify', 'AuthTwoFactorController')->only(['index', 'store']);
Route::prefix('admin')->middleware(['auth','twofactor','can:access_admin_panel'])->namespace('Admin')->name('admin.')->group(function () {
Route::get('/home', 'DashboardController@index')->name('home');
}
and two_factor middleware is
<?php
namespace AppHttpMiddleware;
use Closure;
class TwoFactor
{
/**
* Handle an incoming request.
*
* @param IlluminateHttpRequest $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$user = auth()->user();
if(auth()->check() && $user->two_factor_code)
{
if($user->two_factor_expires_at<now()) //expired
{
$user->resetTwoFactorCode();
auth()->logout();
return redirect()->route('admin.login')->with('error','The two factor code has expired. Please login again.');
}
return redirect()->route('verify.index');
}
return $next($request);
}
}
and below is my TwoFactorController :
<?php
namespace AppHttpControllersAuth;
use AppHttpControllersController;
use AppNotificationsTwoFactorCode;
use IlluminateHttpRequest;
class TwoFactorController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
return view('auth.twoFactor');
}
public function store(Request $request)
{
$request->validate([
'two_factor_code' => 'integer|required',
]);
$user = auth()->user();
if($request->two_factor_code == $user->two_factor_code)
{
$user->resetTwoFactorCode();
return redirect()->route('admin.home');
}
return back()->with('error' , 'The two factor code you have entered does not match');
}
public function resend()
{
$user = auth()->user();
$user->generateTwoFactorCode();
$user->notify(new TwoFactorCode());
return back()->with('success','The two factor code has been sent again');
}
}
}