Larabel - 요청에 따라 세션 저장소가 설정되지 않음
저는 최근에 새로운 Laravel 프로젝트를 만들고 인증 가이드를 따르고 있었습니다.로그인 경로 또는 등록 경로 중 하나를 방문하면 다음 오류가 나타납니다.
ErrorException in Request.php line 775:
Session store not set on request. (View: C:\Users\Matthew\Documents\test\resources\views\auth\register.blade.php)
핵심 Laravel 파일은 편집하지 않았습니다.뷰를 만들고 루트를 루트에 추가했을 뿐입니다.php 파일
// Authentication routes
Route::get('auth/login', ['uses' => 'Auth\AuthController@getLogin', 'as' => 'login']);
Route::post('auth/login', ['uses' => 'Auth\AuthController@postLogin', 'as' => 'login']);
Route::get('auth/logout', ['uses' => 'Auth\AuthController@getLogout', 'as' => 'logout']);
// Registration routes
Route::get('auth/register', ['uses' => 'Auth\AuthController@getRegister', 'as' => 'register']);
Route::post('auth/register', ['uses' => 'Auth\AuthController@postRegister', 'as' => 'login']);
저는 라라벨에 대한 경험이 별로 없기 때문에, 저의 무지를 양해해 주십시오.같은 질문을 하는 다른 질문이 있다는 것은 알지만, 어느 대답도 제게는 맞지 않는 것 같습니다.읽어주셔서 감사합니다!
편집:
여기 제 등록기에요.블레이드.요청하신 대로 php.
@extends('partials.main')
@section('title', 'Test | Register')
@section('content')
<form method="POST" action="/auth/register">
{!! csrf_field() !!}
<div class="ui input">
<input type="text" name="name" value="{{ old('name') }}" placeholder="Username">
</div>
<div class="ui input">
<input type="email" name="email" value="{{ old('email') }}" placeholder="Email">
</div>
<div class="ui input">
<input type="password" name="password" placeholder="Password">
</div>
<div class="ui input">
<input type="password" name="password_confirmation"placeholder="Confirm Password">
</div>
<div>
<button class="ui primary button" type="submit">Register</button>
</div>
</form>
@endsection
세션 상태, CSRF 보호 등이 필요한 경우 웹 미들웨어를 사용해야 합니다.
Route::group(['middleware' => ['web']], function () {
// your routes here
});
를 routes
내 the의 web middleware
안 .이것을 에 추가해 주세요.$middleware
Kernel.php
protected $middleware = [
//...
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
];
내 경우(Larabel 5.3 사용)에 다음 2개의 미들웨어만 추가하면 API 루트의 세션 데이터에 액세스할 수 있었습니다.
\App\Http\Middleware\EncryptCookies::class
\Illuminate\Session\Middleware\StartSession::class
전체 선언($middlewareGroups
Kernel.php):
'api' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Session\Middleware\StartSession::class,
'throttle:60,1',
'bindings',
],
Bloem의되지 않는 즉, Cas Bloem을 있는 )web
applicable route)는Kernel.middleware의 하는 것이 .
는 " " " 입니다.Kernel.php
을 사용하다
$middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
];
:VerifyCsrfToken
에 StartSession
이 있다, 될 Session store not set on request.
★★★★★★ 。
컨트롤러의 기능 내에서 세션에 액세스하려고 하는 것이 문제일 수 있습니다.
Larabel 5.3+부터는 업그레이드가이드에 기재되어 있는 대로 동작하지 않기 때문에 이 기능은 더 이상 사용할 수 없습니다.
이전 버전의 Laravel에서는 세션 변수 또는 컨트롤러의 생성자에서 인증된 사용자에 액세스할 수 있었습니다.이것은 결코 프레임워크의 명시적인 특징을 의도하지 않았다.Larabel 5.3에서는 미들웨어가 아직 실행되지 않았기 때문에 컨트롤러의 컨스트럭터에서 세션 또는 인증된 사용자에 액세스할 수 없습니다.
자세한 배경 정보는 테일러의 답변도 읽어보십시오.
회피책
그래도 사용할 경우 업그레이드가이드의 설명에 따라 미들웨어를 동적으로 생성하여 컨스트럭터에서 실행할 수 있습니다.
또는 컨트롤러의 컨스트럭터에서 직접 Closure 기반 미들웨어를 정의할 수도 있습니다.이 기능을 사용하기 전에 응용 프로그램이 Larabel 5.3.4 이상을 실행하고 있는지 확인하십시오.
<?php namespace App\Http\Controllers; use App\User; use Illuminate\Support\Facades\Auth; use App\Http\Controllers\Controller; class ProjectController extends Controller { /** * All of the current user's projects. */ protected $projects; /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware(function ($request, $next) { $this->projects = Auth::user()->projects; return $next($request); }); } }
라라벨 [5.4]
해결방법은 글로벌세션 도우미 session()을 사용하는 것이었습니다.
기능은 $request->session()보다 조금 어렵습니다.
기입:
session(['key'=>'value']);
푸시:
session()->push('key', $notification);
취득:
session('key');
제 경우 $middleware Groups에 다음 4줄을 추가했습니다(app/Http/Kernel.php).
'api' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
'throttle:60,1',
'bindings',
],
중요: '스로틀' 및 '바인딩' 앞에 4개의 새 줄을 추가해야 합니다!
그렇지 않으면 "CSRF token not match" 오류가 발생합니다.순서가 중요하다는 걸 깨닫기 위해 몇 시간 동안이나 애를 썼죠
이를 통해 API 세션에 액세스할 수 있습니다.또한 쿠키/세션과 관련된 경우 CSRF를 처리해야 하기 때문에 VerifyCsrfToken을 추가했습니다.
저는 Laravel 7.x를 사용하고 있는데 이 문제가 발생했습니다.다음과 같이 수정했습니다.
에 kernel.php
를 2개의 클래스에 합니다.protected $middleware
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
제가 고치다를 붙여서 요.\Illuminate\Session\Middleware\StartSession::class,
api
Kernel만, 가 Kernel에 되었기 때문에, 있는 것을 .php에 있는 미들웨어 그룹입니다만, 인증 루트가 다음에 추가되었기 때문에, 나중에 이것을 「작동」하고 있는 것을 알게 되었습니다.api.php
web.php
그래서 라라벨은 잘못된 인증가드를 사용하고 있었다.
.web.php
부터는 제대로 을 하게 .AuthenticatesUsers.php
삭제:
Route::group(['middleware' => ['guest', 'throttle:10,5']], function () {
Route::post('register', 'Auth\RegisterController@register')->name('register');
Route::post('login', 'Auth\LoginController@login')->name('login');
Route::post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail');
Route::post('password/reset', 'Auth\ResetPasswordController@reset');
Route::post('email/verify/{user}', 'Auth\VerificationController@verify')->name('verification.verify');
Route::post('email/resend', 'Auth\VerificationController@resend');
Route::post('oauth/{driver}', 'Auth\OAuthController@redirectToProvider')->name('oauth.redirect');
Route::get('oauth/{driver}/callback', 'Auth\OAuthController@handleProviderCallback')->name('oauth.callback');
});
Route::post('logout', 'Auth\LoginController@logout')->name('logout');
요.RequestGuard::logout()
을 사용하다
, 하고 있는 알 수 AuthenticatesUsers 의 경우는 .Auth::routes()
네, 네, 네.그 후 라라벨이 기본적으로 웹 가드를 사용하고 있다는 것을 깨달았습니다.그것은 루트가 다음 장소에 있어야 한다는 것을 의미합니다.routes/web.php
.
Sanctum과 분리된 Vue SPA 앱의 현재 설정은 다음과 같습니다.
커널.php
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
'throttle:60,1',
],
];
주의: Laravel Sanctum 및 같은 도메인 Vue SPA에서는 세션쿠키에 httpOnly cookie를 사용하고 CSRF에 대해서는 me cookie 및 unsecure cookie를 사용합니다.
web
auth 및된 JSON 는 JSON을 사용해야 .auth:sanctum
미들웨어
config/auth.displaces
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
...
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
할 수 있는데,서 중요한 것은 '보다 낫다'입니다. ★★★★★★★★★★★★★★★★★★★★★·Auth::check()
,Auth::user()
, , , , 입니다.Auth::logout()
및 합니다.AuthenticatesUsers
그리고.RegistersUsers
특성들.
로그인 유닛 테스트의 몇 가지를 다음에 나타냅니다.
테스트 케이스php
/**
* Creates and/or returns the designated regular user for unit testing
*
* @return \App\User
*/
public function user() : User
{
$user = User::query()->firstWhere('email', 'test-user@example.com');
if ($user) {
return $user;
}
// User::generate() is just a wrapper around User::create()
$user = User::generate('Test User', 'test-user@example.com', self::AUTH_PASSWORD);
return $user;
}
/**
* Resets AuthManager state by logging out the user from all auth guards.
* This is used between unit tests to wipe cached auth state.
*
* @param array $guards
* @return void
*/
protected function resetAuth(array $guards = null) : void
{
$guards = $guards ?: array_keys(config('auth.guards'));
foreach ($guards as $guard) {
$guard = $this->app['auth']->guard($guard);
if ($guard instanceof SessionGuard) {
$guard->logout();
}
}
$protectedProperty = new \ReflectionProperty($this->app['auth'], 'guards');
$protectedProperty->setAccessible(true);
$protectedProperty->setValue($this->app['auth'], []);
}
LoginTest.php
protected $auth_guard = 'web';
/** @test */
public function it_can_login()
{
$user = $this->user();
$this->postJson(route('login'), ['email' => $user->email, 'password' => TestCase::AUTH_PASSWORD])
->assertStatus(200)
->assertJsonStructure([
'user' => [
...expectedUserFields,
],
]);
$this->assertEquals(Auth::check(), true);
$this->assertEquals(Auth::user()->email, $user->email);
$this->assertAuthenticated($this->auth_guard);
$this->assertAuthenticatedAs($user, $this->auth_guard);
$this->resetAuth();
}
/** @test */
public function it_can_logout()
{
$this->actingAs($this->user())
->postJson(route('logout'))
->assertStatus(204);
$this->assertGuest($this->auth_guard);
$this->resetAuth();
}
저는 이 명령어를 덮어썼다.registered
그리고.authenticated
204 OPTIONS가 아닌 사용자 객체를 반환하도록 Laravel auth 특성으로 메서드를 설정합니다.
public function authenticated(Request $request, User $user)
{
return response()->json([
'user' => $user,
]);
}
protected function registered(Request $request, User $user)
{
return response()->json([
'user' => $user,
]);
}
인증 특성의 벤더 코드를 확인합니다.위의 두 가지 방법 외에 사용하지 않고 그대로 사용할 수 있습니다.
- vendor/laravel/ui/auth-backend/RegistersUsers.php
- vendor/laravel/ui/auth-backend/AuthenticatesUsers.php
로그인 시 Vue SPA의 Vuex 액션은 다음과 같습니다.
async login({ commit }, credentials) {
try {
const { data } = await axios.post(route('login'), {
...credentials,
remember: credentials.remember || undefined,
});
commit(FETCH_USER_SUCCESS, { user: data.user });
commit(LOGIN);
return commit(CLEAR_INTENDED_URL);
} catch (err) {
commit(LOGOUT);
throw new Error(`auth/login# Problem logging user in: ${err}.`);
}
},
async logout({ commit }) {
try {
await axios.post(route('logout'));
return commit(LOGOUT);
} catch (err) {
commit(LOGOUT);
throw new Error(`auth/logout# Problem logging user out: ${err}.`);
}
},
Laravel Sanctum + 동일 도메인 Vue SPA + 인증 유닛 테스트를 모두 제 기준에 맞게 진행하는데 일주일 이상 걸렸습니다.이 답변으로 향후 다른 사용자의 시간을 절약할 수 있기를 바랍니다.
같은 에러가 있었지만, 생텀의 설정이 잘못되어 있었습니다.php 파일.스테이트풀 도메인 블록 내에는 아직 프로덕션 도메인이 아닌 개발 도메인이 있었습니다.
'stateful' => explode(',', env(
'SANCTUM_STATEFUL_DOMAINS',
'mydomain.com')
),
똑같은 오류가 발생했습니다.
그게 도움이 됐으면 좋겠어요.
건배.
사용할 수 있습니까?->stateless()
이 되기 전에->redirect()
그럼 세션은 더 이상 필요하지 않습니다.
sanctum을 사용한SPA 인증 테스트 실행 시 이 문제가 발생합니까?
솔루션:
이 행을 에 추가합니다.tests/TestCase.php
:
public function setUp(): void
{
parent::setUp();
$this->withHeader('origin', config('app.url'));
}
설명:
SPA 인증에 sanctum을 사용하려면 API 미들웨어에 다음 항목을 추가해야 합니다.
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class
EnsureFrontendRequestsAreStateful
클래스는 정적 메서드가 있는 경우에만 작동합니다.fromFrontend
true를 반환합니다.
public static function fromFrontend($request)
{
$domain = $request->headers->get('referer') ?: $request->headers->get('origin');
if (is_null($domain)) {
return false;
}
// ... ommited
}
세션 저장소가 설정되지 않은 이유:$domain
유닛 테스트에서 이 메서드가 실행되고 있는 경우는 null이 됩니다.
나의 경우, 그것은 단지 리턴을 넣기 위한 것이었다; 내가 세션을 설정한 기능의 마지막에
CSRF 를 사용하고 있는 경우는, 다음과 같이 입력합니다.'before'=>'csrf'
고객님의 경우Route::get('auth/login', ['before'=>'csrf','uses' => 'Auth\AuthController@getLogin', 'as' => 'login']);
자세한 내용은 Larabel 5 Documentation Security Protecting Routes를 참조하십시오.
라라벨 문서에는 기재되어 있지 않습니다.이것에 1시간이나 걸렸어요.
세션은 "저장" 메서드를 사용할 때까지 지속되지 않았습니다.
$request->session()->put('lang','en_EN');
$request->session()->save();
Larabel 5.3 이상의 웹 미들웨어 그룹은 Route Service Provider에 의해 루트/web.php 파일에 자동으로 적용됩니다.
커널 $middlewareGroups 어레이를 지원되지 않는 순서로 수정하지 않는 한 컨스트럭터로부터의 일반적인 의존관계로서 요구를 주입하려고 합니다.
요청 사용
public function show(Request $request){
}
대신
public function __construct(Request $request){
}
제 경우(Laravel 5.8의 경우)는session.php
에 있는 Laravel 프로젝트의 config 파일../[mylaravelapp]/config/
디렉토리가 없습니다.다른 에서 누락된 했습니다.config
을 사용하다
좋아요, 당신이 직면한 상황은 다음과 같습니다.요청한 요청으로 인스턴스화되지 않은 요청 연결 세션을 호출하고 있습니다.세션 데이터를 사용할 수 있는 요청에 따라 세션을 시작하는 요청에 대해서만 Laravel Session을 설정하면 됩니다.
$request->setLaravelSession(session())
top public/index.displaces를 추가합니다.
ob_start();
공유 호스트를 사용하여 작업합니다.
동작하지 않는 경우는, app/Http/Middleware/TrustProxies 로 이 코드를 변경해 주세요.php
protected $proxies;
로.
protected $proxies = '*';
다음은 나에게 효과가 있다...
사용자가 로그인할 때 세션 만들기
$r->session()->put('usrSession',$r->uName);
여기서 'usrSession'은 내 키이고 'uName'은 요청 변수(실제로 해당 사용자의 고유 사용자 이름)에서 가져옵니다.
사용자가 로그아웃할 때 (모든) 세션 플러시
$r->session()->flush();
언급URL : https://stackoverflow.com/questions/34449770/laravel-session-store-not-set-on-request
'programing' 카테고리의 다른 글
문자열이 비어 있는지 확인하는 방법 (0) | 2023.01.25 |
---|---|
명령줄 ubuntu 16.04에서 php 버전 전환 (0) | 2023.01.25 |
MySQL 오류 1264: 열의 값을 벗어났습니다. (0) | 2023.01.25 |
CommonJs 모듈시스템에서의 "module.exports"와 "exports"의 차이점 (0) | 2023.01.25 |
하나의 캐치 블록에서 여러 예외 유형 포착 (0) | 2023.01.25 |