Laravel-요청시 세션 저장소가 설정되지 않음


113

최근에 새로운 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 파일을 편집하지 않았으며보기 만 만들고 route.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']);

라 라벨에 대한 경험이 많지 않으니 실례합니다. 나는 이와 같은 것을 묻는 또 다른 질문 이 있다는 것을 알고 있지만 대답 중 어느 것도 나를 위해 작동하지 않는 것 같습니다. 읽어 주셔서 감사합니다!

편집하다:

여기에 요청한 register.blade.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

포스트 register.blade.php 코드
드리 Waqas

당신은 또한 단지와 위의 routes.php을 대체 할 수 있습니다Route::controllers([ 'auth' => 'Auth\AuthController', 'password' => 'Auth\PasswordController', ]);
드리 Waqas에게

와 이름이 같은 경로를 가지고, 그것은 잘못, 서로 다른 이름을 가져야한다
xAoc

@Adamnick 게시 및 교체를 시도합니다.
mattrick 2015

세션 드라이버 구성은 어떻게 설정되어 있습니까?
kipzes

답변:


162

세션 상태, CSRF 보호 등이 필요한 경우 웹 미들웨어 를 사용해야합니다 .

Route::group(['middleware' => ['web']], function () {
    // your routes here
});

2
나는 실제로 그것을 가지고 있습니다, 나는 단지 관련 경로를 포함하고있었습니다.
mattrick 2015

아 이제 무슨 말인지 알 겠어요. 루트를 내부로 옮겨서 작동했습니다. 정말 고맙습니다!
mattrick 2015

@mattrick : 안녕하세요 metrix가 동일한 오류를 가져옵니다. 미들웨어 내에서 경로를 이동 한 위치를 설명 할 수 있지만 "지원되는 암호화기를 찾을 수 없습니다. 암호"라는 오류가 표시됩니다.
Vipin Singh

1
@ErVipinSingh 앱 구성에서 32 자 키를 설정해야합니다. 또는 사용php artisan key:generate
Cas Bloem

2
로그인 경로가 API에 있으면 어떻게됩니까?
Jay Bienvenu

56

귀하의 추가하면 routes내부를 web middleware어떤 이유로 작동하지 않음 다음이 추가 시도 $middlewareKernel.php

protected $middleware = [
        //...
        \Illuminate\Session\Middleware\StartSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
];

4
젠장, 이것은 나를 위해 일했지만 해결책이 아니라 "수정"이라는 것이 행복하지 않습니다. 어쨌든 감사합니다!
Rav

1
이것은 나를 위해 그것을 고쳤습니다. 당신에게 @Waiyi 감사
조쉬

1
귀하의 솔루션은 내 문제를 @Waiyl_Karim 수정
Bipul 로이

이것은 나를 위해 일했습니다. 나는 반응 프런트 엔드를 사용하고 있으므로 경로에 반응 라우터를 사용하고 있으므로 경로 그룹이 작동하지 않습니다.
techcyclist

44

제 경우에는 (Laravel 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',
        ],

21

Cas Bloem의 답변이 적용되지 않는 경우 (즉 web, 해당 경로에 미들웨어 가 확실히 있음 ) HTTP 커널에서 미들웨어의 순서를 확인하는 것이 좋습니다.

기본 순서 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.예외가 발생할 수도 있습니다 .


나는 그것을 똑같이 가지고 있습니다. í 여전히 메시지를받습니다. 또한 $ middleware 배열에 StartSession 및 ShareErrorsFromSession을 넣어 보았습니다. 저장 / 프레임 워드도 쓸 수 있습니다. (내가 BTW Wampserver 3을 사용하고 있습니다.)
Meddie

use 'middleware'=> [ 'web', 'youanother.log'],
Kamaro Lambert

3
네! 나는 바보 같았고 알파벳순으로 (강박 장애 때문에) 재정렬 할 것이라고 생각했고 앱이 망가졌습니다. 안타깝게도 다음날까지 테스트를하지 않았기 때문에 여기에 왔습니다. 참고로 5.3의 "웹"미들웨어 그룹의 기본 순서는 EncryptCookies, AddQueuedCookiesToResponse, StartSession, ShareErrorsFromSession, SubstituteBindings, VerifyCsrfToken입니다.
Ixalmida

19

컨트롤러의 기능 내에서 세션액세스 하려고하면 문제가 발생할 수 있습니다 .__constructor()

Laravel 5.3 이상부터는 업그레이드 가이드에 명시된 것처럼 어쨌든 작동하지 않기 때문에 더 이상 불가능합니다 .

이전 버전의 Laravel에서는 컨트롤러 생성자에서 세션 변수 또는 인증 된 사용자에 액세스 할 수있었습니다. 이것은 프레임 워크의 명시적인 기능을 의도 한 것이 아닙니다. Laravel 5.3에서는 미들웨어가 아직 실행되지 않았기 때문에 컨트롤러의 생성자에서 세션이나 인증 된 사용자에 액세스 할 수 없습니다.

더 많은 배경 정보는 Taylor 그의 답변을 읽어보십시오 .

해결 방법

그래도 사용하려면 업그레이드 가이드에 설명 된대로 미들웨어를 동적으로 만들고 생성자에서 실행할 수 있습니다.

대안으로 컨트롤러의 생성자에서 직접 클로저 기반 미들웨어를 정의 할 수 있습니다. 이 기능을 사용하기 전에 애플리케이션이 Laravel 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);
        });
    }
}

1
__constructor () 포인트를 설명해 주셔서 감사합니다. 내 개념을 클리어했다.
Ashish Choudhary

16

라 라벨 [5.4]

내 해결책은 전역 세션 도우미를 사용하는 것이 었습니다. session ()

그 기능은 $ request-> session () 보다 약간 어렵습니다 .

쓰기 :

session(['key'=>'value']);

미는 :

session()->push('key', $notification);

검색 :

session('key');

이것은 우리가 컨트롤러에서 세션 변수를 작성하고 다른 컨트롤러에서 사용할 때 작동하지 않습니다 :(
Kamlesh

3

제 경우에는 $ middlewareGroups (app / Http / Kernel.php에서)에 다음 4 줄을 추가했습니다.

'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',
],

중요 : 'throttle'및 'bindings'전에 4 개의 새 줄을 추가해야합니다!

그렇지 않으면 "CSRF 토큰이 일치하지 않음"오류가 발생합니다. 나는 순서가 중요하다는 것을 알기 위해 몇 시간 동안 이것을 고생했습니다.

이를 통해 API의 세션에 액세스 할 수있었습니다. 쿠키 / 세션이 관련 될 때 CSRF가 처리되어야하기 때문에 VerifyCsrfToken도 추가했습니다.


laravel을 사용하여 api를 작성하는 경우 이것이 원하는 답변입니다. :) 또는 추가 -> stateless ()-> redirect ()
Bobby Ax

2

당신이 사용할 수있는 마십시오 ->stateless()전과 ->redirect(). 그러면 더 이상 세션이 필요하지 않습니다.


0

제 경우에는 단지 반환을하는 것이 었습니다. 내가 세션을 설정 한 기능의 끝에서


0

CSRF를 사용하는 경우 다음을 입력하십시오. 'before'=>'csrf'

귀하의 경우 Route::get('auth/login', ['before'=>'csrf','uses' => 'Auth\AuthController@getLogin', 'as' => 'login']);

자세한 내용은 Laravel 5 문서 보안 보호 경로 를 참조하십시오.


0

laravel 문서에는 없습니다.이 작업을 수행하는 데 한 시간이 걸렸습니다.

내 세션은 "저장"방법을 사용할 때까지 지속되지 않았습니다.

$request->session()->put('lang','en_EN');
$request->session()->save();

0

Laravel 5.3+ 웹 미들웨어 그룹은 RouteServiceProvider에 의해 route / web.php 파일에 자동으로 적용됩니다.

지원되지 않는 순서로 커널 $ middlewareGroups 배열을 수정하지 않는 한 생성자의 일반 종속성으로 요청을 삽입하려고 할 수 있습니다.

다음으로 요청 사용

public function show(Request $request){

}

대신에

public function __construct(Request $request){

}

0

Laravel Sanctum에서이 오류가 발생했습니다. 나는 추가하여 고정 \Illuminate\Session\Middleware\StartSession::class,받는 apiKernel.php에서 미들웨어 그룹,하지만 내 인증 경로가 추가 되었기 때문에이 "일"에서 나중에 생각 api.php대신web.php Laravel 잘못된 인증 가드를 사용 그래서.

이 경로를 여기로 옮겼고 특성 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()를 수행하는 데 사용하지 않았습니다 . 그런 다음 Laravel은 기본적으로 웹 가드를 사용하며 경로가 routes/web.php.

Sanctum과 분리 된 Vue SPA 앱을 사용하면 내 설정이 다음과 같이 표시됩니다.

Kernel.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 쿠키를 사용하고, me 쿠키를 기억하고 CSRF에 대해 비보안 쿠키를 기억하므로 web인증을 위해 가드를 사용하고 다른 모든 보호 된 JSON 반환 경로는 auth:sanctum미들웨어.

config / auth.php

'defaults' => [
    'guard' => 'web',
    'passwords' => 'users',
],

...

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'token',
        'provider' => 'users',
        'hash' => false,
    ],
],

그런 다음 이와 같은 단위 테스트를 수행 할 수 있습니다. 여기서 비판적 Auth::check()으로 Auth::user(),, 그리고 Auth::logout()최소한의 구성과 최대 사용 AuthenticatesUsersRegistersUsers특성 으로 예상대로 작동 합니다.

다음은 몇 가지 로그인 단위 테스트입니다.

TestCase.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();
}

204 OPTIONS 대신 사용자 객체를 반환하도록 Laravel 인증 특성 의 registeredauthenticated메서드를 재정의했습니다 .

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 + 인증 단위 테스트가 모두 내 표준에 맞게 작동하는 데 일주일 이상 걸렸으므로 여기에있는 내 답변이 향후 다른 사람들의 시간을 절약하는 데 도움이되기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.