Laravel - Oturum deposu istek üzerine ayarlanmadı


114

Yakın zamanda yeni bir Laravel projesi oluşturdum ve Kimlik Doğrulama kılavuzunu takip ediyordum. Girişimi veya kayıt rotamı ziyaret ettiğimde aşağıdaki hatayı alıyorum:

ErrorException in Request.php line 775:
Session store not set on request. (View: C:\Users\Matthew\Documents\test\resources\views\auth\register.blade.php)

Herhangi bir çekirdek Laravel dosyasını düzenlemedim, sadece görünümleri oluşturdum ve rotaları route.php dosyama ekledim

// 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']);

Laravel ile pek tecrübem yok, bu yüzden lütfen cehaletimi bağışlayın. Aynı şeyi soran başka bir soru olduğunun farkındayım , ancak yanıtların hiçbiri benim için işe yaramıyor gibi görünüyor. Okuduğunuz için teşekkürler!

Düzenle:

İstenildiği gibi register.blade.php burada.

@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

post register.blade.php kodu
Chaudhry Waqas

ayrıca sadece yukarıda routes.php yerini alabilirRoute::controllers([ 'auth' => 'Auth\AuthController', 'password' => 'Auth\PasswordController', ]);
Chaudhry waqas

ve aynı isimli rotalarınız var, bu yanlış, farklı isimleri olmalı
xAoc

@Adamnick Gönderildi ve değiştirmeyi deneyecek.
mattrick

Oturum sürücüsü yapılandırmanız nasıl ayarlandı?
24'te kipzes

Yanıtlar:


166

Oturum durumuna, CSRF korumasına ve daha fazlasına ihtiyacınız varsa web ara yazılımını kullanmanız gerekir.

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

2
Aslında buna sahibim, sadece ilgili rotaları ekledim.
mattrick

Ah şimdi ne demek istediğini anlıyorum, yolları içeri taşıdım ve işe yaradı. Çok teşekkür ederim!
mattrick

@mattrick: merhaba metrix aynı hatayı alıyor. Ara yazılım içinde rotaları nereye taşıdığınızı açıklayabilir misiniz, ancak "Desteklenen bir şifreleyici bulunamadı. Şifre" hatasını gösteriyor.
Vipin Singh

1
@ErVipinSingh, uygulama yapılandırmanızda 32 karakterlik bir anahtar ayarlamanız gerekir. Veya kullanınphp artisan key:generate
Cas Bloem

2
Ya oturum açma rotanız API içindeyse?
Jay Bienvenu

56

Senin ekleyerek Eğer routesiçini web middlewareherhangi bir nedenle does not work sonra bu eklemeyi deneyin $middlewareiçineKernel.php

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

4
Kahretsin, bu benim için çalıştı, ancak bunun bir "düzeltme", bir çözüm olmadığı için mutlu değilim. Yine de teşekkürler!
Rav

1
Bu benim için düzeltti. Teşekkür ederim @Waiyi
Josh

1
Çözümünüz sorunumu çözüyor @Waiyl_Karim
Bipul Roy

Bu benim için çalıştı. Bir react ön ucu kullanıyorum, böylece rotalar için react router kullandığım için rota grubu çalışmıyor.
techcyclist

44

Benim durumumda (Laravel 5.3 kullanarak) yalnızca aşağıdaki 2 ara yazılımı eklemek API rotalarımdaki oturum verilerine erişmeme izin verdi:

  • \App\Http\Middleware\EncryptCookies::class
  • \Illuminate\Session\Middleware\StartSession::class

Tüm beyanname ($middlewareGroups Kernel.php'de):

'api' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Session\Middleware\StartSession::class,
            'throttle:60,1',
            'bindings',
        ],

21

Cas Bloem'in cevabı geçerli değilse (yani kesinlikle web , ilgili rotada ara katman yazılımınız varsa), HTTP Çekirdeğinizdeki ara yazılımların sırasını kontrol etmek isteyebilirsiniz.

Varsayılan sıra Kernel.phpşudur:

$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,
    ],
];

Daha VerifyCsrfTokensonra geldiğini unutmayın StartSession. Bunları farklı bir sırada aldıysanız, aralarındaki bağımlılık da Session store not set on request.istisnaya yol açabilir .


bende aynen böyle var. Hala mesajı alıyorum. Ayrıca StartSession ve ShareErrorsFromSession'ı $ middleware dizisine koymayı denedim. Storate / frameword da yazılabilir. (Wampserver 3 btw kullanıyorum.)
Meddie

'ara yazılım' kullan => ['web', 'youanother.log'],
Kamaro Lambert

3
Evet! Aptaldım ve bunları alfabetik olarak yeniden sıralayacağımı düşündüm (çünkü OKB) ve bu, uygulamayı bozdu. Ne yazık ki, ertesi güne kadar test yapmadım, bu yüzden buraya geldim. Sadece kayıt için, 5.3'teki "web" ara yazılım grubu için varsayılan sıra şudur: EncryptCookies, AddQueuedCookiesToResponse, StartSession, ShareErrorsFromSession, SubstituteBindings, VerifyCsrfToken.
Ixalmida

19

Bir sorun, kontrol cihazınızın işlevi içinde oturumunuza erişmeye çalışmanız olabilir .__constructor()

Laravel 5.3+ sürümünden itibaren bu artık mümkün değildir çünkü yükseltme kılavuzunda belirtildiği gibi zaten çalışması amaçlanmamaktadır .

Laravel'in önceki sürümlerinde, denetleyicinizin kurucusundaki oturum değişkenlerine veya kimliği doğrulanmış kullanıcıya erişebiliyordunuz. Bunun hiçbir zaman çerçevenin açık bir özelliği olması amaçlanmadı. Laravel 5.3'te, ara yazılım henüz çalışmadığı için denetleyicinizin yapıcısındaki oturuma veya kimliği doğrulanmış kullanıcıya erişemezsiniz.

Daha fazla arka plan bilgisi için Taylor'ın cevabını da okuyun .

Geçici çözüm

Hala bunu kullanmak istiyorsanız, yükseltme kılavuzunda açıklandığı gibi dinamik olarak bir ara katman yazılımı oluşturabilir ve yapıcıda çalıştırabilirsiniz:

Alternatif olarak, doğrudan denetleyicinizin yapıcısında Closure tabanlı bir ara yazılım tanımlayabilirsiniz. Bu özelliği kullanmadan önce, uygulamanızın Laravel 5.3.4 veya üstünü çalıştırdığından emin olun:

<?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 () noktasını açıkladığınız için teşekkür ederiz. Kavramlarımı temizledim.
Ashish Choudhary

16

Laravel [5.4]

Benim çözümüm global oturum yardımcısını kullanmaktı: session ()

İşlevselliği $ request-> session () ' dan biraz daha zordur .

yazma :

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

itme :

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

alma :

session('key');

Bu, bir denetleyiciye oturum değişkenini yazdığımızda ve başka bir denetleyicide kullandığımızda çalışmıyor :(
Kamlesh

4

Benim durumumda $ middlewareGroups'a aşağıdaki 4 satırı ekledim (app / Http / Kernel.php içinde):

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

ÖNEMLİ: 4 yeni çizgi, 'gaz' ve 'bağlamalar'dan ÖNCE eklenmelidir!

Aksi takdirde "CSRF jetonu eşleşmiyor" hatası yükselecektir. Sırf sıranın önemli olduğunu bulmak için birkaç saat boyunca bu konuda mücadele ettim.

Bu, API'mdeki oturuma erişmeme izin verdi. Çerezler / oturumlar söz konusu olduğunda CSRF ile ilgilenilmesi gerektiği için VerifyCsrfToken'ı da ekledim.


Laravel ile apis yazıyorsanız, aradığınız cevap budur :) veya ekleyin -> stateless () -> redirect ()
Bobby Ax,

2

->stateless()Önce kullanabilirsiniz ->redirect(). O zaman artık seansa ihtiyacınız yok.




0

Laravel belgelerinde yok, bunu başarmak için bir saatim oldu:

"Kaydet" yöntemini kullanana kadar oturumum devam etmedi ...

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

0

Laravel 5.3+ web ara yazılım grubu, RouteServiceProvider tarafından otomatik olarak route / web.php dosyanıza uygulanır.

Çekirdek $ middlewareGroups dizisini desteklenmeyen bir sırayla değiştirmediğiniz sürece, muhtemelen istekleri yapıcıdan düzenli bir bağımlılık olarak enjekte etmeye çalışıyorsunuzdur.

İsteği şu şekilde kullan

public function show(Request $request){

}

onun yerine

public function __construct(Request $request){

}

0

Laravel Sanctum ile bu hatayı alıyordum. Kernel.php'deki ara yazılım grubuna ekleyerek \Illuminate\Session\Middleware\StartSession::class,bunu apidüzelttim, ancak daha sonra bunun "işe yaradığını" anladım çünkü kimlik doğrulama yollarım api.phpyerine eklendiweb.php laravel yanlış yetkilendirme görevlisi kullanıyordum yüzden.

Bu rotaları buraya taşıdım web.phpve sonra AuthenticatesUsers.phpözellik ile düzgün bir şekilde çalışmaya başladılar :

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');

Hakkında garip bir hata daha aldım sonra sorunu çözdüm RequestGuard::logout() .

Özel kimlik doğrulama yollarımın AuthenticatesUsers özelliğinden yöntemler çağırdığını fark etmemi sağladı, ancak bunu Auth::routes()başarmak için kullanmıyordum . Sonra Laravel'in varsayılan olarak web korumasını kullandığını fark ettim ve bu, rotalarınroutes/web.php .

Sanctum ve ayrıştırılmış bir Vue SPA uygulamasıyla ayarlarım şimdi şöyle görünüyor:

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

Not: Laravel Sanctum ve aynı alan adına sahip Vue SPA ile oturum tanımlama bilgisi için httpOnly tanımlama bilgilerini kullanırsınız ve beni hatırla tanımlama bilgisini ve CSRF için güvenli olmayan tanımlama bilgisini kullanırsınız, bu nedenle webkorumayı yetkilendirme için kullanırsınız ve diğer tüm korumalı, JSON döndürme rotalarını kullanmalısınız. auth:sanctumara yazılım.

config / auth.php

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

...

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

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

Sonra böyle kritik, bu nereye olarak birim testleri olabilir Auth::check(), Auth::user()ve Auth::logout()çalışma olarak Asgari yapılandırma ve maksimum kullanımı ile beklenen AuthenticatesUsersve RegistersUsersözellikleri.

İşte giriş birimi testlerimden birkaçı:

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

Laravel kimlik doğrulama özelliklerinde registeredve authenticatedyöntemlerini geçersiz kıldım, böylece yalnızca 204 SEÇENEK yerine kullanıcı nesnesini döndürdüler:

public function authenticated(Request $request, User $user)
{
    return response()->json([
        'user' => $user,
    ]);
}

protected function registered(Request $request, User $user)
{
    return response()->json([
        'user' => $user,
    ]);
}

Yetkilendirme özellikleri için satıcı koduna bakın. Bunları el değmeden ve ayrıca yukarıdaki iki yöntemi kullanabilirsiniz.

  • vendor / laravel / ui / auth-backend / RegistersUsers.php
  • vendor / laravel / ui / auth-arka uç / AuthenticatesUsers.php

İşte benim Vue SPA'mın giriş için Vuex eylemleri:

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 + aynı alanlı Vue SPA + kimlik doğrulama ünitesi testlerini standartıma uygun şekilde çalıştırmam bir haftadan fazla sürdü, bu yüzden umarım buradaki cevabım gelecekte başkalarına zaman kazandırabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.