laravel 5.7 multi auth email verification - laravel

I'm new to Laravel and I'm trying to set up an email verification for job_seeker but after I register a new job_seeker I redirect to profile page which must be protected with job_seeker_verified middleware
in normal case I must be redirecting to job_seeker/verify which uses the route named job_seeker_verification.notice with the controller verification_controller and the function that shows the view with verify message but instead I get
forbidden page 403
namespace App\Http\Controllers\job_seeker;
use App\Job_seeker;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class job_seeker_profile_controller extends Controller
{
public function __construct()
{
$this->middleware(['job_seeker_auth', 'job_seeker_verified']);
}
public function show_profile(Job_seeker $job_seeker)
{
return view('profile.job_seeker_profile');
}
}
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Support\Facades\Auth;
use Closure;
class Ensure_Job_Seeker_Is_Verified
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
$guard == 'job_seeker';
if (
!Auth::guard($guard)->user() || (Auth::guard($guard)->user() instanceof MustVerifyEmail &&
!Auth::guard($guard)->user()->hasVerifiedEmail())
) {
return $request->expectsJson()
? abort(403, 'Your email address is not verified.')
: Redirect::route('job_seeker_verification.notice');
}
return $next($request);
}
}
namespace App\Http\Controllers\job_seeker;
use Illuminate\Http\Request;
use App\Job_seeker;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\VerifiesEmails;
class Verification_Controller extends Controller
{
use VerifiesEmails;
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
protected $redirectTo = 'job_seeker.profile';
public function __construct()
{
$this->middleware('job_seeker_auth');
$this->middleware('signed');
$this->middleware('throttle:6,1')->only('resend');
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show(Request $request)
{
return $request->user()->hasVerifiedEmail()
? redirect($this->redirectPath())
: view('profile.job_seeker_verify');
}
public function verify(Request $request)
{
if ($request->route('id') != $request->user()->getKey()) {
throw new AuthorizationException;
}
if ($request->user()->hasVerifiedEmail()) {
return redirect($this->redirectPath());
}
if ($request->user()->markEmailAsVerified()) {
event(new Verified($request->user()));
}
return redirect($this->redirectPath())->with('job_seeker_verified', true);
}
}
Route::get('job_seeker_email.resend', [
'as'=>'job_seeker_email.verification.resend', 'uses'=>'job_seeker\Job_Seeker_Verication_email#resend'
]);
Route::get('job_seeker/verify', [
'as'=>'job_seeker_verification.notice', 'uses'=>'job_seeker\Verification_Controller#show'
]);
Route::get('job_seeker/verify/{id}', [
'as'=>'job_seeker_verification.verify','uses'=>'job_seeker\Verification_Controller#verify'
]);

Remove
$this->middleware('job_seeker_auth');
From the verification_controller constructor because it's returning 403 before it reaches the show or verify method
An unverified user can't verify themselves if they need to be verified to do so

Related

Laravel 8 Multi Auth with Jetstream livewire

im trying to setup a multi auth system in laravel 8 with jetstream livewire in my ecomm project (one login page for admins(/admin/login) and another for users(/login))
i have followed a tutorial and everything is ok expect when i login to user from /login page i can access /admin/dashboard with that user and with admin its fine and cant access user /dashboard
routes\web.php:
Route::get('/', function () {
return view('welcome');
});
Route::group(['prefix'=>'admin','middleware'=>['admin:admin']],function(){
Route::get('/login', [AdminController::class, 'loginForm']);
Route::post('/login', [AdminController::class, 'store'])->name('admin.login');
Route::get('/logout', [AdminController::class, 'Logout'])->name('admin.logout');
});
Route::middleware(['auth:sanctum,admin', 'verified'])->get('/admin/dashboard', function () {
return view('admin.index');
})->name('dashboard.admin');
Route::middleware(['auth:sanctum,web', 'verified'])->get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
Models\Admin.php:
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Jetstream\HasProfilePhoto;
use Laravel\Sanctum\HasApiTokens;
class Admin extends Authenticatable
{
use HasApiTokens;
use HasFactory;
use HasProfilePhoto;
use Notifiable;
use TwoFactorAuthenticatable;
/**
* 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',
'two_factor_recovery_codes',
'two_factor_secret',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* The accessors to append to the model's array form.
*
* #var array
*/
protected $appends = [
'profile_photo_url',
];
}
Controllers\AdminController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Contracts\Auth\StatefulGuard;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use Illuminate\Routing\Pipeline;
use App\Actions\Fortify\AttemptToAuthenticate;
use Laravel\Fortify\Actions\EnsureLoginIsNotThrottled;
use Laravel\Fortify\Actions\PrepareAuthenticatedSession;
use App\Actions\Fortify\RedirectIfTwoFactorAuthenticatable;
use App\Http\Responses\LoginResponse;
use Laravel\Fortify\Contracts\LoginViewResponse;
use Laravel\Fortify\Contracts\LogoutResponse;
use Laravel\Fortify\Features;
use Laravel\Fortify\Fortify;
use Laravel\Fortify\Http\Requests\LoginRequest;
use Auth;
class AdminController extends Controller
{
/**
* The guard implementation.
*
* #var \Illuminate\Contracts\Auth\StatefulGuard
*/
protected $guard;
/**
* Create a new controller instance.
*
* #param \Illuminate\Contracts\Auth\StatefulGuard
* #return void
*/
public function __construct(StatefulGuard $guard, Request $request)
{
$this->guard = $guard;
}
public function loginForm(){
return view('admin.login',['guard'=>'admin']);
}
public function Logout(){
Auth::logout();
return Redirect()->url('admin/login')->with('success', 'Logged Out');
}
/**
* Show the login view.
*
* #param \Illuminate\Http\Request $request
* #return \Laravel\Fortify\Contracts\LoginViewResponse
*/
public function create(Request $request): LoginViewResponse
{
return app(LoginViewResponse::class);
}
/**
* Attempt to authenticate a new session.
*
* #param \Laravel\Fortify\Http\Requests\LoginRequest $request
* #return mixed
*/
public function store(LoginRequest $request)
{
return $this->loginPipeline($request)->then(function ($request) {
return app(LoginResponse::class);
});
}
/**
* Get the authentication pipeline instance.
*
* #param \Laravel\Fortify\Http\Requests\LoginRequest $request
* #return \Illuminate\Pipeline\Pipeline
*/
protected function loginPipeline(LoginRequest $request)
{
if (Fortify::$authenticateThroughCallback) {
return (new Pipeline(app()))->send($request)->through(array_filter(
call_user_func(Fortify::$authenticateThroughCallback, $request)
));
}
if (is_array(config('fortify.pipelines.login'))) {
return (new Pipeline(app()))->send($request)->through(array_filter(
config('fortify.pipelines.login')
));
}
return (new Pipeline(app()))->send($request)->through(array_filter([
config('fortify.limiters.login') ? null : EnsureLoginIsNotThrottled::class,
Features::enabled(Features::twoFactorAuthentication()) ? RedirectIfTwoFactorAuthenticatable::class : null,
AttemptToAuthenticate::class,
PrepareAuthenticatedSession::class,
]));
}
/**
* Destroy an authenticated session.
*
* #param \Illuminate\Http\Request $request
* #return \Laravel\Fortify\Contracts\LogoutResponse
*/
public function destroy(Request $request): LogoutResponse
{
$this->guard->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return app(LogoutResponse::class);
}
}
Responses\LoginResponse.php:
<?php
namespace App\Http\Responses;
use Laravel\Fortify\Contracts\LoginResponse as LoginResponseContract;
class LoginResponse implements LoginResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* #param \Illuminate\Http\Request $request
* #return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
return $request->wantsJson()
? response()->json(['two_factor' => false])
: redirect()->intended('admin/dashboard');
}
}
i also created a copy of StatefulGuard in App\Guards\AdminStatefulGuard.php following that tutorial but never used it.
Problem fixed by adding this code to my admin controllers.
public function __construct()
{
$this->middleware(['auth:admin,admin', 'verified']);
}
and also replacing this in web route:
Route::middleware(['auth:sanctum,admin', 'verified'])->get('/admin/dashboard', function () {
return view('admin.index');
})->name('dashboard.admin');
with this:
Route::middleware(['auth:admin,admin', 'verified'])->get('/admin/dashboard', function () {
return view('admin.index');
})->name('dashboard.admin');
Try this on Admin middleware
public function handle(Request $request, Closure $next, $guard)
{
if (Auth::guard($guard)->check()) {
return redirect('/admin/dashboard');
}
if(Auth::guard('web')->check()) {
return redirect('/dashboard');
}
return $next($request);
}
and on RedirectIfAuthenticated middleware:
public function handle(Request $request, Closure $next, ...$guards)
{
$guards = empty($guards) ? [null] : $guards;
foreach ($guards as $guard) {
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);
}
}
if(Auth::guard('admin')->check()) {
return redirect('admin/dashboard');
}
return $next($request);
}

Prevent login to user and custom guards at the same time

I am using a custom guard for a different type of user using a custom guard labelled business_user.
I have noticed I am able to login to as both normal users (web) and my business_users.
I've read in the Pusher documentation that I used to create my custom guards in the first place to add additional middleware into my "LoginController".
But I don't actually even have a LoginController, I've created my own controllers for each user type. AuthController (for web) and BusinessController (for business_user).
I have created a third controller labelled LoginController with the following code:
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = '/dashboard';
public function __construct()
{
$this->middleware('guest')->except('logout');
$this->middleware('guest:business_user')->except('logout');
}
}
I also updated my RedirectIfAuthenticated as follows:
class RedirectIfAuthenticated
{
public function handle($request, Closure $next, $guard = null)
{
if ($guard == "business_user" && Auth::guard($guard)->check()) {
return redirect('/dashboard');
}
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);
}
return $next($request);
}
I also have a RedirectIfAuthenticated middleware inside my Middleware folder.
<?php
namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if ($guard == "business_user" && Auth::guard($guard)->check()) {
return redirect('/dashboard');
}
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);
}
return $next($request);
}
}
When I land on my user login page, it still allows me to attempt logging in. Can someone tell me how to resolve this?
In LoginController, you can override authenticated method.
/**
* The user has been authenticated.
*
* #param \Illuminate\Http\Request $request
* #param mixed $user
* #return mixed
*/
protected function authenticated(Request $request, $user)
{
auth()->login($user); // this method will login with default guard
return redirect()->intended($this->redirectPath());
}
I think because the order of middleware
<?php
public function __construct()
{
$this->middleware('guest')->except('logout'); // this procress first and redirect to login page
$this->middleware('guest:business_user')->except('logout');
}
So, I think you can check directly in __construct() of LoginController or in login view (blade file)
#if (Auth::check('business_user'))
You are already logged in (or perform a redirect somewhere)
#else
//display login form
#endif

Laravel 6 - How to restrict route by user field value?

Atm, I use a steamauth API to grab a users steamid and pass it into user->steamid, but I want to restrict it to, if the field named steamid in users is not null(has already a steamid) they cant enter the route and will get a redirect back. I have tried for several hours now, but i cant seem to get it to working. This is my AuthController atm:
use Invisnik\LaravelSteamAuth\SteamAuth;
use App\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
class AuthController extends Controller
{
/**
* The SteamAuth instance.
*
* #var SteamAuth
*/
protected $steam;
/**
* The redirect URL.
*
* #var string
*/
protected $redirectURL = '/';
/**
* AuthController constructor.
*
* #param SteamAuth $steam
*/
public function __construct(SteamAuth $steam)
{
$this->steam = $steam;
$this->middleware('auth');
}
/**
* Redirect the user to the authentication page
*
* #return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function redirectToSteam()
{
return $this->steam->redirect();
}
/**
* Get user info and log in
*
* #return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function handle()
{
if ($this->steam->validate()) {
$info = $this->steam->getSteamId();
if (!is_null($info)) {
Auth::user()->update(['steamid' => $info]);
return redirect($this->redirectURL); // redirect to site
}
}
return $this->redirectToSteam();
}
Added this custom middleware and it works:
public function handle($request, \Closure $next)
{
/*$user = User::where('steamid', $request)->first();
if (!is_null($user)) {
return redirect('/profile');
}*/
if ($request->user()->steamid !== null){
return redirect('/profile')->with('denied', 'Du kan kun tilføje én steamprofil');
}
return $next($request);
}

View [auth.login] not found

I am working on login part of application where i am creating two seperate login for admin and user.
My Controller structure is like :
Controller - Admin (For Admin)
LoginController.php
-- Auth
login.blade.php
.... Auth (For Normal user)
LoginController.php
...
Views:
Admin
login.blade.php
auth
login.blade.php
till now i'm working on the admin part.
LoginController.php
<?php
namespace App\Http\Controllers\Admin;
use Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
/**
* Where to redirect admins after login.
*
* #var string
*/
protected $redirectTo = '/admin';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest:admin')->except('logout');
}
/**
* #return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function showLoginForm()
{
return view('admin.auth.login');
}
public function login()
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
if (Auth::guard('admin')->attempt([
'email' => $request->email,
'password' => $request->password
], $request->get('remember'))) {
return redirect()->intended(route('admin.dashboard'));
}
return back()->withInput($request->only('email', 'remember'));
}
/**
* #param Request $request
* #return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
/*public function logout(Request $request)
{
Auth::guard('admin')->logout();
$request->session()->invalidate();
return redirect()->route('admin.login');
} */
}
RedirectIfAuthenticated.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
switch($guard){
case 'admin':
if (Auth::guard($guard)->check()) {
return redirect('/admin');
}
break;
default:
if (Auth::guard($guard)->check()) {
return redirect('/');
}
break;
}
return $next($request);
}
}
Authenticate.php
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* #param \Illuminate\Http\Request $request
* #return string
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('login');
}
}
}
web.php
Route::group(['prefix' => 'admin'], function () {
Route::get('login', 'Admin\LoginController#showLoginForm')->name('admin.login');
Route::post('login', 'Admin\LoginController#login')->name('admin.login.post');
Route::get('logout', 'Admin\LoginController#logout')->name('admin.logout');
//Route::get('dashboard', 'Admin\LoginController#dashboard')->name('admin.dashboard');
Route::group(['middleware' => ['auth:admin']], function () {
Route::get('/dashboard', function () {
return view('admin.dashboard.index');
})->name('admin.dashboard');
});
whenever i access dashboard throgh url i get View[auth.login] not found.
You can modify the file Authenticate.php to receive the guard name in redirectTo method.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
class Authenticate extends Middleware
{
/**
* #var array
*/
protected $guards = [];
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string[] ...$guards
* #return mixed
*
* #throws \Illuminate\Auth\AuthenticationException
*/
public function handle($request, Closure $next, ...$guards)
{
$this->guards = $guards;
return parent::handle($request, $next, ...$guards);
}
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* #param \Illuminate\Http\Request $request
* #return string
*/
protected function redirectTo($request)
{
if (!$request->expectsJson()) {
if (reset($this->guards) === 'admin') {
return route('admin.login');
}
return route('login');
}
}
}
Note that it may be necessary to execute php artisan cache:clear after the change.
source

More than one header issue

<?php namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\RegisterRequest;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\Registrar;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use App\Http\Requests\LoginRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\URL;
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;
/**
* For redirect after registeration
* #return mixed
*/
public function redirectPath()
{
// return property_exists($this, 'redirectTo') ? $this->redirectTo : '/user/profile/';
//return property_exists($this, 'redirectTo') ? $this->redirectTo : '/';
return Redirect::intended('/');
}
/**
* Create a new authentication controller instance.
*
* #param \Illuminate\Contracts\Auth\Guard $auth
* #param \Illuminate\Contracts\Auth\Registrar $registrar
* #return \App\Http\Controllers\Auth\AuthController
*/
public function __construct(Guard $auth, Registrar $registrar)
{
$this->auth = $auth;
$this->registrar = $registrar;
$this->middleware('guest', ['except' => 'getLogout']);
}
/**
* Handle a login request to the application.
*
* #param LoginRequest $request
* #return Response
*/
public function postLogin(LoginRequest $request)
{
if ($this->auth->attempt($request->only('email', 'password')))
{
if(Auth::user()->is_admin)
return redirect('/admin');
else {
return Redirect::intended('/');
}
}
return redirect('auth/login')->withErrors([
'email' => 'The credentials you entered did not match our records. Try again?',
]);
}
}
I am redirecting a user to an intended url after signup but i get the following error.
Header may not contain more than a single header, new line detected
This is the code in the AuthController.
public function redirectPath()
{
return Redirect::intended('/');
}
And the following is the code in the Authenticate class.
public function handle($request, Closure $next)
{
if ($this->auth->guest())
{
if ($request->ajax())
{
return response('Unauthorized.', 401);
}
else
{
return redirect()->guest('auth/register');
}
}
return $next($request);
}
I am using laravel 5

Resources