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안 .이것을 에 추가해 주세요.$middlewareKernel.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
전체 선언($middlewareGroupsKernel.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,apiKernel만, 가 Kernel에 되었기 때문에, 있는 것을 .php에 있는 미들웨어 그룹입니다만, 인증 루트가 다음에 추가되었기 때문에, 나중에 이것을 「작동」하고 있는 것을 알게 되었습니다.api.phpweb.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를 사용합니다.
webauth 및된 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그리고.authenticated204 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클래스는 정적 메서드가 있는 경우에만 작동합니다.fromFrontendtrue를 반환합니다.
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 |