我试图通过Laravel护照设置会话时遇到错误
“消息”:“未根据请求设置会话存储。”, “ exception”:“ RuntimeException”,
答案 0 :(得分:0)
Laravel Passport是用于laravel的基于令牌的身份验证程序包
API通常使用令牌来验证用户身份,并且不维护 请求之间的会话状态。 Laravel使API身份验证成为可能 使用Laravel Passport轻轻松松,它提供了完整的OAuth2服务器 只需几分钟即可实现Laravel应用程序的实现。
默认情况下,包括oAuth2在内的几乎所有基于令牌的系统都是无状态的,这意味着没有会话与其关联,
这意味着没有会话存储。您只能依靠每个请求提供的令牌来验证用户身份。
这就是为什么使用laravel护照时无法设置会话
答案 1 :(得分:0)
这可以通过多种方式完成。
StartSession
之后添加auth:api
中间件。这是最直接的解决方案。在auth:api
之后添加以下三行。
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
然后从中删除\Illuminate\View\Middleware\ShareErrorsFromSession::class
middlewarePriority
受保护的财产。没有这个StartSession
中间件,将在{strong>之前 auth
以及更重要的是在EncryptCookies
中间件之前获得控制,而这些中间件基本上会导致新的会话。>
<?php
namespace App\Http;
class Kernel extends HttpKernel
{
// Copy this values from
// \Illuminate\Foundation\Http\Kernel::$middlewarePriority
// then remove or comment line with StartSession. Without it,
// StartSession middleware will get control right before Auth.
// Which, basically, will create a new session because at this
// time cookies are still encrypted.
protected $middlewarePriority = [
// \Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Auth\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
...
],
'api' => [
'throttle:120,1',
'bindings',
'auth:api', // https://laravel.com/docs/5.7/passport#protecting-routes
// Add the following three middleware right after `auth`
// in order to have a session.
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSession::class,
],
];
}
StartSession
中间件。拥有自己的中间件来开始会话,将使您不必覆盖middlewarePriority
。
首先,创建一个新类。
<?php
namespace App\Http\Middleware;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\Session\SessionManager;
class StartSessionShared extends StartSession
{
public function __construct(Application $app, SessionManager $manager)
{
parent::__construct($manager);
$app->singleton(StartSessionShared::class);
}
}
然后在auth:api
之后添加以下三行。
EncryptCookies::class,
AddQueuedCookiesToResponse::class,
StartSessionShared::class,
此方法中的一个重要说明是调用$app->singleton
。没有它,Laravel将始终创建此类的新实例。这将导致\Illuminate\Session\Middleware\StartSession::terminate
方法跳过保存会话。
StartSessionReadonly
中间件。如果您只想共享来自web
的会话,这是一个不错的选择
警惕api
警惕,并且无意以任何方式更改其值。这是我的情况。
创建以下StartSessionReadonly
中间件。然后在api
卫队中使用它,而不是StartSession
及其两个朋友。
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Contracts\Encryption\Encrypter;
use Illuminate\Contracts\Session\Session;
use Illuminate\Http\Request;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\Session\SessionManager;
/**
* Middleware for sharing session between `web` and `api` guards.
* Since the latter is essentially stateless, the session from
* `web` is shared as readonly.
*
* @package App\Http\Middleware
*/
class StartSessionReadonly extends StartSession
{
protected $encrypter;
public function __construct(Encrypter $encrypter, SessionManager $manager)
{
parent::__construct($manager);
$this->encrypter = $encrypter;
}
public function handle($request, Closure $next)
{
// If a session driver has been configured, we will need to start the session here
// so that the data is ready for an application. Note that the Laravel sessions
// do not make use of PHP "native" sessions in any way since they are crappy.
if ($this->sessionConfigured()) {
$request->setLaravelSession($this->startSession($request));
}
return $next($request);
}
public function getSession(Request $request)
{
return tap($this->manager->driver(), function (Session $session) use ($request) {
$payload = $request->cookies->get($session->getName());
$unserialize = EncryptCookies::serialized($session->getName());
try {
$session->setId($this->encrypter->decrypt($payload, $unserialize));
}
catch (DecryptException $exception) {
}
});
}
}
更新app/Http/Kernel.php
后,您将拥有所有api的只读会话。
<?php
namespace App\Http;
class Kernel extends HttpKernel
{
[...]
/****
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
[...]
'api' => [
'throttle:120,1',
'bindings',
'auth:api', // https://laravel.com/docs/5.7/passport#protecting-routes
StartSessionReadonly::class,
],
];