#php #laravel #session #caching #csrf
Вопрос:
Фон
Я создал пользовательское промежуточное программное обеспечение аутентификации, чтобы проверить, вошел ли пользователь в систему. Если зарегистрированный пользователь посещает страницу входа в систему, она перенаправляет его на панель мониторинга. Если пользователь, не вошедший в систему, посещает страницу панели мониторинга, она перенаправляет его на страницу входа в систему. Я использую LaravelLocalization в качестве многоязычного плагина.
Проблема
Во время тестирования все работает нормально. Я смог войти в систему, сеанс сохранен, ошибок 419 нет. Однако, когда я возвращаюсь, чтобы снова попытаться войти в систему, я встречаю ошибку 419 с истекшим сроком действия страницы. Я читал много постов об этом, и большинство из них советуют добавить другую форму @csrf в форму, которую, кажется, я уже сделал. Затем я попытался отключить проверку csrf с помощью дополнения
$except = ['*']
VerifyCsrfToken.php
. Затем 419 исчезает, но сеанс не работает. После входа в систему он успешно перенаправляется на панель мониторинга, но после обновления сеанс теряется и снова перенаправляется на страницу входа. Проблема может быть временно решена путемphp artisan cache:clear
Пожалуйста, посоветуйте. Я даже не знаю, с чего начать отладку.
Middleware/CustomAuth.php
<?php
namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpRequest;
use McamaraLaravelLocalizationFacadesLaravelLocalization;
class CustomAuth
{
/**
* Handle an incoming request.
*
* @param IlluminateHttpRequest $request
* @param Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next)
{
if(!(session()->has('logged_affiliate'))
amp;amp; $request->path() != 'user-login'
amp;amp; $request->path() != 'user-register'
amp;amp; $request->path() != LaravelLocalization::getCurrentLocale()."/user-login"
amp;amp; $request->path() != LaravelLocalization::getCurrentLocale()."/user-register"
){
return redirect(LaravelLocalization::localizeUrl("/user-login"))->with('fail',__('word.login_first'));
}
if(session()->has('logged_affiliate')
amp;amp; (
$request->path() == 'user-login'
|| $request->path() == 'user-register'
|| $request->path() == LaravelLocalization::getCurrentLocale()."/user-login"
|| $request->path() == LaravelLocalization::getCurrentLocale()."/user-register"
)
){
return redirect(LaravelLocalization::localizeUrl("/affiliate"));
}
// if(session()->has('logged_advertiser') amp;amp; ( $request->path() == 'user-login' || $request->path() == 'user-register' )){
// return redirect('/advertiser');
// }
return $next($request);
}
}
Маршрут
Затем в файле маршрута я заворачиваю эти маршруты в ['middleware'=>['CustomAuth']
<?php
use IlluminateSupportFacadesRoute;
Route::prefix(LaravelLocalization::setLocale())->middleware(['localeSessionRedirect', 'localizationRedirect'])->group(function () {
//other route
Route::group(['middleware'=>['CustomAuth']],function(){
Route::get('/user-login',[AppHttpControllersUserController::class,'showLogin']);
Route::get('/user-register',[AppHttpControllersUserController::class,'showRegister']);
//this is the user dashboard
Route::get('/affiliate',[AppHttpControllersUserController::class,'showAffiliateDashboard']);
Route::get('/affiliate/website-list',[AppHttpControllersUserController::class,'affiliate_website_list']);
//some similar routes
});
//submit form
Route::post('/check',[AppHttpControllersUserController::class,'checkLogin'])->name('checkLogin');
Route::post('/user-register',[AppHttpControllersUserController::class,'createAccount'])->name('create_account');
Route::post('/affiliate-add-website',[AppHttpControllersUserController::class,'affiliate_add_website'])->name('affiliate_add_website');
Route::post('/affiliate-edit-website',[AppHttpControllersUserController::class,'affiliate_edit_website'])->name('affiliate-edit-website');
Route::get('/logout',[AppHttpControllersUserController::class,'logout'])->name('logout');
Route::post('/license/check',[AppHttpControllersUserController::class,'affiliate_use_license'])->name('affiliate_use_license');
//other route
});
View and form
Then the user login form, I added @csrf
<form action="{{ LaravelLocalization::localizeUrl("/check") }}" method="POST">
@csrf
<div class="form-group">
<label>{{ __('word.username') }}</label>
<input type="text" class="form-control" name="username" value="{{ old('username') }}">
<span class="text-danger">@error('username'){{ $message }} @enderror</span>
</div>
<div class="form-group">
<label>{{ __('word.password') }} ({{ __('word.password_hint') }})</label>
<input type="password" class="form-control" name="password">
<span class="text-danger">@error('password'){{ $message }} @enderror</span>
</div>
<div class="mt-4">
<div class="row">
<div class="col-12">
<button type="submit" class="btn btn-outline-primary btn-block btn-lg submit-btn">
<i class="spinner fa fa-spinner fa-spin" aria-hidden="true"></i> {{ __('word.signin') }}
</button>
</div>
</div>
</div>
@if(Session::get('fail'))
<div class="alert alert-danger mt-3">
{{ Session::get('fail') }}
</div>
@endif
</form>
Controller
This is UserController to check credential. If checked correct, save into session $request->session()->put('logged_affiliate',$user->username);
public function checkLogin(Request $request)
{
$request->validate(
[
'username' => ['required'],
'password' => ['required'],
// 'user_type' => ['required'],
],
[
'username.required' => __('word.username_required'),
'password.required' => __('word.password_required'),
// 'user_type.required' => __('word.user_type_required'),
],
);
$user = User::where('username',$request->username)->first();
if(!$user){
return back()->with('fail',__('word.no_such_user'));
}else{
if(Hash::check($request->password,$user->password)){
if($user->user_type == 'affiliate'){
$request->session()->put('logged_affiliate',$user->username);
return redirect(LaravelLocalization::localizeURL('/affiliate'));
}elseif($user->user_type == 'advertiser'){
$request->session()->put('logged_advertiser',$user->id);
return redirect(LaravelLocalization::localizeURL('/advertiser'));
}else{
return back()->with('fail',__('word.something_wrong'));
}
}else{
return back()->with('fail',__('word.wrong_password'));
}
}
}
//Affiliate Dashboard Pages
public function showAffiliateDashboard()
{
$lang = CommonController::get_lang();
$affiliate_data = CommonController::get_affiliate_data();
$ads = CommonController::get_ads();
$user_data = User::where('user_type','affiliate')->where('username', session('logged_affiliate'))->first();
$user_websites = Affiliate::where('affiliate_id',session('logged_affiliate'))->get();
$active_level_1 = Affiliate::where('affiliate_id',session('logged_affiliate'))->where('active',1)->where('level',1)->count();
$active_level_2 = Affiliate::where('affiliate_id',session('logged_affiliate'))->where('active',1)->where('level',2)->count();
return view('users.affiliateDashboard',compact(
'lang','affiliate_data','ads',
'user_data','user_websites',
'active_level_1','active_level_2',
));
}