मुझे यह त्रुटि Laravel Sanctum के साथ मिल रही थी। मैं जोड़कर तय \Illuminate\Session\Middleware\StartSession::class,
करने के लिए api
Kernel.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 + को प्राप्त करने के लिए मुझे एक सप्ताह से अधिक का समय लग गया है। मेरी इकाई सभी मानक पर काम कर रही है, इसलिए उम्मीद है कि मेरा उत्तर यहाँ भविष्य में दूसरों का समय बचाने में मदद कर सकता है।