Я создаю API для своего приложения для Android, используя laravel и драйвер сеанса по умолчанию, установленный в REDIS.
Я нашел хорошую статью здесь http://dor.ky/laravel-prevent-sessions-for-routes-via-a-filter/, которая служит цели.
Однако когда я ударяю URL-адрес, он также попадает в redis и генерирует ключ, который пуст. Теперь я хочу избежать создания пустых ключей сеанса в redis. В идеале это не должно ударить redis. Как я могу это сделать?
Можем ли мы настроить sessios таким образом, чтобы сеансы генерировались только для определенных маршрутов (или отключались для определенных маршрутов)?
Я могу объяснить больше с конкретным вариантом использования, пожалуйста, дайте мне знать.
Его очень легко использовать промежуточное ПО в Laravel 5, мне нужен был любой запрос с ключом API, чтобы не иметь сеанс, и я просто сделал:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Session\Middleware\StartSession as BaseStartSession; class StartSession extends BaseStartSession { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if(\Request::has('api_key')) { \Config::set('session.driver', 'array'); } return parent::handle($request, $next); } }
Также вам необходимо расширить SessionServiceProvider следующим образом:
<?php namespace App\Providers; use Illuminate\Session\SessionServiceProvider as BaseSessionServiceProvider; class SessionServiceProvider extends BaseSessionServiceProvider { /** * Register the service provider. * * @return void */ public function register() { $this->registerSessionManager(); $this->registerSessionDriver(); $this->app->singleton('App\Http\Middleware\StartSession'); } }
и поместите в свой config/app.php
под providers
:
'App\Providers\SessionServiceProvider',
Также вы должны изменить его в своем файле ядра: App/Http/Kernel.php
, в разделе $middlewareGroups
измените запись по умолчанию, \Illuminate\Session\Middleware\StartSession::class,
на новый класс \App\Http\Middleware\StartSession::class,
В Laravel 5 просто не используйте средства StartSession
, ShareErrorsFromSession
и VerifyCsrfToken
.
В моем приложении я переместил эти три middlewares из web
группы в новую группу с stateful
, а затем включил эту группу с stateful
на маршрутах, которые должны знать о сеансе (в дополнение к web
во всех случаях, в моем приложении на наименее). Другие маршруты принадлежат либо к web
либо к группам api
.
Теперь, когда вы делаете запросы к маршрутам, которые не используют сессию сеанса stateful
промежуточным программным обеспечением, не отправляются обратно.
Самый простой способ добиться этого – сделать свое собственное промежуточное ПО AppStartSession, которое подклассы Illuminate \ Session \ Middleware \ StartSession и заменить класс, используемый в kernel.php. Единственный метод, который необходимо переопределить в вашем подклассе, – sessionConfigured (), для которого вы можете вернуть false, чтобы отключить сеанс или родительский :: sessionConfigured (), чтобы разрешить его.
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Session\Middleware\StartSession; class AppStartSession extends StartSession { protected function sessionConfigured(){ if(!\Request::has('api_key')){ return false; }else{ return parent::sessionConfigured(); } } }
kernel.php (см. комментарий ***, где происходит изменение)
<?php namespace App\Http; use Illuminate\Foundation\Http\Kernel as HttpKernel; class Kernel extends HttpKernel { /** * The application's global HTTP middleware stack. * * @var array */ protected $middleware = [ \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, // *** Replace start session class // \Illuminate\Session\Middleware\StartSession::class, \App\Http\Middleware\AppStartSession::class, // *** Also comment these ones that depend on there always being a session. //\Illuminate\View\Middleware\ShareErrorsFromSession::class, //\App\Http\Middleware\VerifyCsrfToken::class, ]; /** * The application's route middleware. * * @var array */ protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, ]; }
Не сражайтесь с каркасом, обнимайте его!
Я пытаюсь выполнить аналогичную функцию.
Наш API является апатридом, за исключением 1 маршрута – корзины версии 1.
Я закончил с установкой 'driver'
в app / config / session.php, как это …
'driver' => 'v1/cart' === Request::getDecodedPath() ? 'native' : 'array',
Ничего волшебного. Первоначально мы, однако, использовали фильтр before, но этого не происходило достаточно рано.
Кажется, это простой способ сделать что-то, но я могу что-то упустить.
Помещение коммутатора в конфигурацию кажется легким местом для других разработчиков, чтобы увидеть, что такое драйвер, тогда как его размещение в провайдере услуг настолько убрано с пути, не зная, какие поставщики услуг установлены и с чем они взаимодействуют, было бы гораздо сложнее отладить.
Так или иначе. Надеюсь, это будет полезно.
Как указано ниже … НЕ СКАЖИТЕ ВАШУ КОНФИГУЦИЮ, ЕСЛИ ДИНАМИКА.
Это приводит к ограниченному использованию. Как только нам больше не нужно поддерживать v1 / cart, мы отбросим этот маршрут, а затем вернемся к статической конфигурации.
Кажется, есть способ сделать это, используя обратный вызов отклонения сеанса.
Соответствующие источники …
https://github.com/laravel/framework/blob/4.2/src/Illuminate/Foundation/Application.php#L655
https://github.com/laravel/framework/blob/4.2/src/Illuminate/Foundation/Application.php#L660
https://github.com/laravel/framework/blob/4.2/src/Illuminate/Session/Middleware.php#L60
https://github.com/laravel/framework/blob/4.2/src/Illuminate/Session/Middleware.php#L97
Я не могу найти много ссылок на это в Интернете, но, прочитав больше через источник, кажется, что если отказ от ответа на вызов возвращает правдивое значение, сеанс будет вынужден использовать драйвер массива для запроса, а не все настроенное , Обратный вызов также получает текущий запрос, поэтому вы можете сделать некоторую логику на основе параметров запроса.
Я тестировал это только на локальной установке Laravel 4.2, но, похоже, это работает. Вам просто нужно привязать функцию к session.reject.
Сначала создайте SessionRejectServiceProvider (или что-то в этом роде)
<?php use \Illuminate\Support\ServiceProvider; class SessionRejectServiceProvider extends ServiceProvider { public function register() { $me = $this; $this->app->bind('session.reject', function($app)use($me){ return function($request)use($me){ return call_user_func_array(array($me, 'reject'), array($request)); }; }); } // Put the guts of whatever you want to do in here, in this case I've // disabled sessions for every request that is an Ajax request, you // could do something else like check the path against a list and // selectively return true if there's a match. protected function reject($request) { return $request->ajax(); } }
Затем добавьте его своим провайдерам в приложение / config / app.php
<?php return array( // ... other stuff 'providers' => array( // ... existing stuff... 'SessionRejectServiceProvider', ), );
Конечным результатом является то, что метод reject () вызывается при каждом запросе вашего приложения до начала сеанса. Если ваш метод reject () возвращает true, сеансы будут установлены на драйвер массива и в основном ничего не делают. Вы можете найти много полезной информации для параметра $ request, чтобы определить это, вот ссылка API для объекта запроса в 4.2.
Начиная с Laravel 5.2, когда были введены группы промежуточного программного обеспечения, вы можете отключить сеанс для определенных маршрутов, указав их вне группы «промежуточного программного обеспечения» (включая промежуточное ПО StartSession, ответственное за обработку сеанса). Как и в последних версиях версии 5.2.x, весь файл default.php по умолчанию обернут группой промежуточного программного обеспечения «web», вам необходимо внести некоторые изменения в файл app/Providers/RouteServiceProvider.php
, как описано здесь .