लारवेल - सत्र दुकान अनुरोध पर सेट नहीं है


114

मैंने हाल ही में एक नया लारवेल प्रोजेक्ट बनाया था और ऑथेंटिकेशन पर गाइड के साथ चल रहा था। जब मैं अपने लॉगिन या रजिस्टर मार्ग पर जाता हूं, तो मुझे निम्नलिखित त्रुटि मिलती है:

ErrorException in Request.php line 775:
Session store not set on request. (View: C:\Users\Matthew\Documents\test\resources\views\auth\register.blade.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

post register.blade.php कोड
चौधरी वकास

आप उपरोक्त मार्गों को भी बदल सकते हैं। बसRoute::controllers([ 'auth' => 'Auth\AuthController', 'password' => 'Auth\PasswordController', ]);
चौधरी वकास

और आपके पास एक ही नाम वाले मार्ग हैं, यह गलत है, उनके अलग-अलग नाम होने चाहिए
xAoc

@Adamnick ने पोस्ट किया और इसे बदलने का प्रयास करेगा।
मैट्रिक

आपका सत्र ड्राइवर कॉन्फ़िगरेशन कैसे सेट किया जाता है?
kipzes

जवाबों:


165

यदि आपको सत्र राज्य, CSRF सुरक्षा और अधिक की आवश्यकता है, तो आपको वेब मिडिलवेयर का उपयोग करना होगा ।

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

2
मेरे पास वास्तव में ऐसा है, मैं संबंधित मार्गों को शामिल कर रहा था।
मैट्रिक

आह, मैं देख रहा हूं कि अब आपका क्या मतलब है, मैंने मार्गों को अंदर स्थानांतरित कर दिया और यह काम कर गया। आपको बहुत - बहुत धन्यवाद!
मैट्रिक

@ मैट्रिक: हाय मेट्रिक्स एक ही त्रुटि हो रही है। आप समझा सकते हैं कि आपने बीचवेयर में मार्गों को कहां स्थानांतरित किया है, लेकिन यह त्रुटि दिखा रहा है "कोई समर्थित एनक्रिप्ट नहीं मिला। सिफर"।
विपिन सिंह

1
@ErVipinSingh आपको अपने ऐप कॉन्फिगर में एक 32 कैरेक्टर की की को सेट करना होगा। या उपयोग करेंphp artisan key:generate
कैस ब्लोम

2
यदि आपका लॉगिन मार्ग एपीआई में है तो क्या होगा?
Jay Bienvenu

56

यदि आपका जोड़ने routesके अंदर web middlewareकिसी भी कारण से नहीं काम तो करने के लिए इस जोड़ने की कोशिश $middlewareमेंKernel.php

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

4
अरे, यह मेरे लिए काम किया है, लेकिन मुझे खुशी नहीं है कि यह एक "फिक्स" है, न कि समाधान। फिर भी धन्यवाद!
रवि

1
इसने मेरे लिए इसे ठीक कर दिया। थैंक्यू @Waiyi
जोश

1
आपका समाधान मेरी समस्या को हल करता है @Waiyl_Karim
बिपुल रॉय

इसने मेरे लिए काम किया। मैं एक प्रतिक्रिया दृश्य का उपयोग कर रहा हूँ इसलिए मार्ग समूह काम नहीं करता है क्योंकि मैं मार्गों के लिए प्रतिक्रिया रूटर का उपयोग कर रहा हूं।
टेकसाइकलिस्ट

44

मेरे मामले में (लारवेल 5.3 का उपयोग करके) केवल निम्नलिखित 2 मिडलवेयर को जोड़ने से मुझे मेरे एपीआई मार्गों में सत्र डेटा का उपयोग करने की अनुमति मिली:

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

संपूर्ण घोषणा ( $middlewareGroupsकर्नेल में)

'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.अपवाद को जन्म दे सकती है।


मेरे पास ऐसा ही है। मुझे अभी भी संदेश मिला है। मैंने $ मिडलवेयर सरणी में StartSession और ShareErrorsFromSession डालने की भी कोशिश की। Storate / frameword भी लेखन योग्य है। (मैं
Wampserver

'मिडलवेयर' => ['वेब', 'youanother.log'] का उपयोग करें,
कामरो लैम्बर्ट

3
हां! मैं गूंगा था और सोचा था कि मैं उन वर्णानुक्रम (क्योंकि ओसीडी) को फिर से चलाऊंगा और इसने ऐप को तोड़ दिया। दुर्भाग्य से, मैंने अगले दिन तक परीक्षण नहीं किया, यही वजह है कि मैं यहाँ समाप्त हुआ। सिर्फ रिकॉर्ड के लिए, 5.3 में "वेब" मिडिलवेयर समूह के लिए डिफ़ॉल्ट क्रम है: एनक्रिप्ट्रीज, एडक्यूक्यूइक्यूसीटिसट्रेस, स्टार्टसेशन, शेयरएयरफोर्सफ्रेमसैंस, सब्स्टीट्यूटबैंकिंग, वेरिफायर्सक्रॉफ्ट टोकेन।
Ixalmida 14

19

एक समस्या यह हो सकती है कि आप अपने नियंत्रक के कार्य के अंदर सत्र का उपयोग करने का प्रयास करें __constructor()

लारवेल 5.3+ से यह अब संभव नहीं है क्योंकि यह वैसे भी काम करने का इरादा नहीं है, जैसा कि उन्नयन गाइड में कहा गया है

लारवेल के पिछले संस्करणों में, आप सत्र चर या अपने नियंत्रक के निर्माता में प्रमाणित उपयोगकर्ता तक पहुंच सकते हैं। यह फ्रेमवर्क की एक स्पष्ट विशेषता होने का इरादा नहीं था। लारवेल 5.3 में, आप अपने नियंत्रक के निर्माण में सत्र या प्रमाणित उपयोगकर्ता तक नहीं पहुंच सकते हैं क्योंकि मिडलवेयर अभी तक नहीं चला है।

अधिक पृष्ठभूमि की जानकारी के लिए टेलर ने उनकी प्रतिक्रिया भी पढ़ी ।

वैकल्पिक हल

यदि आप अभी भी इसका उपयोग करना चाहते हैं, तो आप गतिशील रूप से एक मिडलवेयर बना सकते हैं और इसे कंस्ट्रक्टर में चला सकते हैं, जैसा कि अपग्रेड गाइड में वर्णित है:

एक विकल्प के रूप में, आप अपने नियंत्रक के निर्माता में सीधे क्लोजर आधारित मिडलवेयर को परिभाषित कर सकते हैं। इस सुविधा का उपयोग करने से पहले, सुनिश्चित करें कि आपका आवेदन 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 () बिंदु को समझाने के लिए धन्यवाद। मेरी अवधारणाओं को साफ कर दिया।
आशीष चौधरी

16

लारवेल [5.4]

मेरा समाधान वैश्विक सत्र सहायक का उपयोग करना था: सत्र ()

इसकी कार्यक्षमता $ अनुरोध की तुलना में थोड़ी कठिन है-> सत्र ()

लेखन :

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

धक्का :

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

पुनः प्राप्त करना :

session('key');

जब हम एक नियंत्रक में सत्र चर लिखते हैं और किसी अन्य नियंत्रक में उपयोग करते हैं तो यह काम नहीं कर रहा है :(
कमलेश

4

मेरे मामले में मैंने निम्न 4 पंक्तियों को $ मिडलवेयरग्रुप्स में जोड़ा है (ऐप / 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 टोकन मैच नहीं" त्रुटि बढ़ जाएगी। मैं इस क्रम में कई घंटों से संघर्ष कर रहा हूं ताकि यह पता चले कि आदेश महत्वपूर्ण है।

इसने मुझे अपने एपीआई में सत्र का उपयोग करने की अनुमति दी। जब कुकीज़ / सत्र शामिल हैं, तब भी मैंने VerifyCsrfToken को जोड़ा था, CSRF को ध्यान रखने की आवश्यकता है।


यदि आप लारवेल के साथ एपीस लिख रहे हैं तो यह उत्तर आपकी तलाश है :) या जोड़ें -> स्टेटलेस () -> रीडायरेक्ट ()
बॉबी एक्स


0

मेरे मामले में यह सिर्फ वापसी करने के लिए था; फ़ंक्शन के अंत में जहां मैंने सत्र सेट किया है


0

यदि आप CSRF दर्ज का उपयोग कर रहे हैं 'before'=>'csrf'

आपके मामले में Route::get('auth/login', ['before'=>'csrf','uses' => 'Auth\AuthController@getLogin', 'as' => 'login']);

अधिक जानकारी के लिए लारवेल 5 डॉक्यूमेंटेशन सिक्योरिटी प्रोटेक्टिंग रूट्स देखें


0

यह लार्वा दस्तावेज पर नहीं है, मुझे इसे प्राप्त करने में एक घंटा लगा है:

जब तक मैंने "सेव" पद्धति का उपयोग नहीं किया तब तक मेरा सत्र जारी रहा ...

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

0

Laravel 5.3+ वेब मिडलवेयर समूह स्वचालित रूप से अपने मार्गों / web.php फ़ाइल को RouteServiceProvider द्वारा लागू किया जाता है।

जब तक आप एक असमर्थित क्रम में कर्नेल $ मिडलवेयरग्रुप्स सरणी को संशोधित नहीं करते हैं, शायद आप निर्माणकर्ता से नियमित निर्भरता के रूप में अनुरोधों को इंजेक्ट करने की कोशिश कर रहे हैं।

अनुरोध के रूप में उपयोग करें

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()मौजूद नहीं है।

इसने मुझे एहसास दिलाया कि मेरे कस्टम ऑर्ट रूट ऑथेंटिकेट्सयूजर विशेषता से कॉल कर रहे हैं, लेकिन मैं Auth::routes()इसे पूरा करने के लिए उपयोग नहीं कर रहा था । तब मुझे एहसास हुआ कि लारवेल डिफ़ॉल्ट रूप से वेब गार्ड का उपयोग करता है और इसका मतलब है कि मार्गों को अंदर होना चाहिए routes/web.php

यह मेरी सेटिंग अब सैंक्चुम के साथ दिखती है और एक 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',
    ],
];

नोट: लारवेल सैंक्चुअम और उसी-डोमेन Vue SPA के साथ, आप सत्र कुकी के लिए httpOnly कुकी का उपयोग करते हैं, और मुझे कुकी, और 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()के रूप में काम कम से कम config और का अधिक से अधिक उपयोग के साथ की उम्मीद AuthenticatesUsersहै और RegistersUsersलक्षण।

यहाँ मेरे लॉगिन इकाई परीक्षण के एक जोड़े हैं:

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

मैंने registeredऔर authenticatedलारवेल के गुण लक्षण में तरीकों को ओवरराइड किया ताकि वे केवल 204 विकल्पों के बजाय उपयोगकर्ता ऑब्जेक्ट वापस करें:

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

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

ऑर्टिकल लक्षण के लिए वेंडर कोड देखें। आप उन्हें अछूता उपयोग कर सकते हैं, साथ ही उन दो तरीकों से ऊपर।

  • विक्रेता / laravel / ui / Auth-बैकएंड / RegistersUsers.php
  • विक्रेता / laravel / ui / Auth-बैकएंड / 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 + को प्राप्त करने के लिए मुझे एक सप्ताह से अधिक का समय लग गया है। मेरी इकाई सभी मानक पर काम कर रही है, इसलिए उम्मीद है कि मेरा उत्तर यहाँ भविष्य में दूसरों का समय बचाने में मदद कर सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.