csrf_field 代码实现追到后面找不到 token 方法

一切从csrf_token()辅助函数开始

 function csrf_token()
    {
        $session = app('session');

        if (isset($session)) {
            return $session->token();
        }

        throw new RuntimeException('Application session store not set.');
    }

app()方法是获取容器实例的,所以我想从绑定实例开始查找于是查到了Illuminate\Foundation中的registerCoreContainerAliases方法

//......省略
 'session'              => [\Illuminate\Session\SessionManager::class]
 //.....省略

在这个类中也没有找到这个token()方法

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
Marrigan
最佳答案

www.php.net/manual/zh/language.oop... 魔术方法了解下 :grin:

3年前 评论
讨论数量: 6
leo

SessionManager 的父类 Manager 定义了 __call 方法

3年前 评论
Marrigan

www.php.net/manual/zh/language.oop... 魔术方法了解下 :grin:

3年前 评论
<?php

namespace Illuminate\Support\Facades;

/**
 * @method static string getName()
 * @method static string getId()
 * @method static void setId(string $id)
 * @method static bool start()
 * @method static bool save()
 * @method static array all()
 * @method static bool exists(string|array $key)
 * @method static bool has(string|array $key)
 * @method static mixed get(string $key, $default = null)
 * @method static mixed pull(string $key, $default = null)
 * @method static void put(string|array $key, $value = null)
 * @method static string token()
 * @method static mixed remove(string $key)
 * @method static void forget(string|array $keys)
 * @method static void flush()
 * @method static bool migrate(bool $destroy = false)
 * @method static bool isStarted()
 * @method static string|null previousUrl()
 * @method static void setPreviousUrl(string $url)
 * @method static \SessionHandlerInterface getHandler()
 * @method static bool handlerNeedsRequest()
 * @method static void setRequestOnHandler(\Illuminate\Http\Request $request)
 * @method static void push(string $key, mixed $value)
 *
 * @see \Illuminate\Session\SessionManager
 * @see \Illuminate\Session\Store
 */
class Session extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'session';
    }
}

这个文件有说让你看 Illuminate\Session\Store 呀

3年前 评论

@兜兜转转便是空 没有经过这个文件吧 我刚追踪在__call在这个魔术方法下最终追到的地方就是 Illuminate\Session->createNativeDriver

 /**
     * Create an instance of the file session driver.
     *
     * @return \Illuminate\Session\Store
     */
    protected function createNativeDriver()
    {
        $lifetime = $this->config->get('session.lifetime');
        return $this->buildSession(new FileSessionHandler(
            $this->container->make('files'), $this->config->get('session.files'), $lifetime
        ));
    }

最终打印结果

Illuminate\Session\Store {#242 ▼
  #id: "wc8226iVqQO2KGqf0yTyRfgk5G2ZfpZdnfXkRlCp"
  #name: "laravel_session"
  #attributes: []
  #handler: Illuminate\Session\FileSessionHandler {#241 ▶}
  #started: false
}
3年前 评论

@Marrigan 我在继续追的时候 

 /**
     * Dynamically call the default driver instance.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        dd($this->driver());
        return $this->driver()->$method(...$parameters);
    }

这里打印的结果

Illuminate\Session\Store {#242 ▼
  #id: "mVDAqDc346RYeoxKxK9N8HS1VE9N4xDh9y5ERLMA"
  #name: "laravel_session"
  #attributes: array:3 [▼
    "_token" => "ZLsaRyPvqwfXu9nCtKak00tK0sGg4wNGB7lwLM8o"
    "_previous" => array:1 []
    "_flash" => array:2 []
  ]
  #handler: Illuminate\Session\FileSessionHandler {#241 ▶}
  #started: true
}

attributes有值

 /**
     * Get a driver instance.
     *
     * @param  string  $driver
     * @return mixed
     *
     * @throws \InvalidArgumentException
     */
    public function driver($driver = null)
    {
        $driver = $driver ?: $this->getDefaultDriver();
        if (is_null($driver)) {
            throw new InvalidArgumentException(sprintf(
                'Unable to resolve NULL driver for [%s].', static::class
            ));
        }

        // If the given driver has not been created before, we will create the instances
        // here and cache it so we can return it next time very quickly. If there is
        // already a driver created by this name, we'll just return that instance.
        if (! isset($this->drivers[$driver])) {
            $this->drivers[$driver] = $this->createDriver($driver);
        }
        dd($this->drivers[$driver]);
        return $this->drivers[$driver];
    }

打印结果

Illuminate\Session\Store {#242 ▼
  #id: "Yg86oD0ITAvsmsYNNWEViqKtDNsJmxzhMnTCD47L"
  #name: "laravel_session"
  #attributes: []
  #handler: Illuminate\Session\FileSessionHandler {#241 ▶}
  #started: false
}

attributes无值

3年前 评论
leo 3年前
MasterPoser (作者) (楼主) 3年前
leo 3年前
MasterPoser (作者) (楼主) 3年前

StartSession 中间件中会调用 session storestart 方法:

Illuminate\Session\Middleware\StartSession

public function handle($request, Closure $next)
{
    ...
    return $this->handleStatefulRequest($request, $session, $next);
    ...
}

protected function handleStatefulRequest(Request $request, $session, Closure $next)
{
    ...
    $request->setLaravelSession(
        $this->startSession($request, $session)
    );
   ...
}

protected function startSession(Request $request, $session)
{
    return tap($session, function ($session) use ($request) {
        $session->setRequestOnHandler($request);

        $session->start();
    });
}

start 方法,会看情况生成 _token

Illuminate\Session\Store

public function start()
{
    ...
    $this->regenerateToken();
    ....
}

public function regenerateToken()
{
    $this->put('_token', Str::random(40));
}

csrf_token 就是获取当前 session 中的这个 _token

token 方法,是通过 Illuminate\Support\Manager::__call 来调用当前 session 中的 token 方法。

当前 session,根据代码和默认配置,是在 Illuminate\Session\SessionManager::createFileDriver 创建的,就是个 Illuminate\Session\Store

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!