No Laravel Sessions for Bots

烈酒焚心 提交于 2019-12-05 03:44:00

问题


I'm having problems with a big Laravel project and the Redis storage. We store our sessions in Redis. We already have 28GB of RAM there. However, it still runs relatively fast to the limit, because we have very many hits (more than 250,000 per day) from search engine bots.

Is there any elegant way to completely disable sessions for bots? I have already implemented my own session middleware, which looks like this:

<?php

namespace App\Http\Middleware;

use App\Custom\System\Visitor;

class StartSession extends \Illuminate\Session\Middleware\StartSession
{
    protected function getSessionLifetimeInSeconds()
    {
        if(Visitor::isBot()) {
            return 1;
        }

        return ($this->manager->getSessionConfig()['lifetime'] ?? null) * 60;
    }

    protected function sessionIsPersistent(array $config = null)
    {
        if(Visitor::isBot()) {
            return false;
        }

        $config = $config ?: $this->manager->getSessionConfig();

        return ! in_array($config['driver'], [null, 'array']);
    }
}

This is my function for detecting bots:

public static function isBot()
    {
        $exceptUserAgents = [
            'Googlebot',
            'Bingbot',
            'Yahoo! Slurp',
            'DuckDuckBot',
            'Baiduspider',
            'YandexBot',
            'Sogou',
            'facebot',
            'ia_archiver',
        ];

        if(!request()->header('User-Agent') || !str_contains(request()->header('User-Agent'), $exceptUserAgents)) {
            return false;
        }

        return true;
    }

Unfortunately, this does not seem to work. Does anyone have a tip or experience here? Thank you very much!


回答1:


This is how I solved this for myself.

  1. Include a bot detection package using composer. I used this one: https://github.com/JayBizzle/Crawler-Detect

    composer require jaybizzle/crawler-detect

  2. Create a new middleware class

namespace App\Http\Middleware;

class NoSessionForBotsMiddleware
{
    public function handle($request, \Closure $next)
    {
        if ((new \Jaybizzle\CrawlerDetect\CrawlerDetect)->isCrawler()) {
            \Config::set('session.driver', 'array');
        }

        return $next($request);
    }
}
  1. Register the middleware before session middleware in the Kernel class:
protected $middlewareGroups = [
    'web' => [
        // ..
        NoSessionForBotsMiddleware::class,
        StartSession::class,
        // ..
    ],
    // ..
];



回答2:


Your problem could be that you're not identifying robots correctly, so it would be helpful to provide the code for that.

Specific to writing middleware that disables sessions, you're much better off changing the session driver to the array driver as that driver does not persist sessions, instead of changing the configuration of the real session driver at runtime.

<?php

namespace App\Http\Middleware;

use App\Custom\System\Visitor;
use Illuminate\Support\Facades\Config;

class DiscardSessionIfBot
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (Visitor::isBot()) {
            Config::set('session.driver', 'array');
        }

        return $next($request);
    }
}


来源:https://stackoverflow.com/questions/51176946/no-laravel-sessions-for-bots

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!