一、属性
1. $_csrfToken 用于csrf验证的令牌
// csrf验证的令牌
private $_csrfToken;
二、方法
1. getCsrfToken方法,返回csrf验证的token
//返回用于csrf验证的令牌
public function getCsrfToken($regenerate = false)
{
if ($this->_csrfToken === null || $regenerate) {
//从cookie或session获取token
$token = $this->loadCsrfToken();
//重新生成token
if ($regenerate || empty($token)) {
$token = $this->generateCsrfToken();
}
//进一步掩码处理
$this->_csrfToken = Yii::$app->security->maskToken($token);
}
return $this->_csrfToken;
}
2. loadCsrfToken方法,从cookie或session获取令牌
// 从cookie或session中获取csrf令牌
protected function loadCsrfToken()
{
//如果启用了cookie来持久化token,
//这里就从cookie中获取
if ($this->enableCsrfCookie) {
return $this->getCookies()->getValue($this->csrfParam);
}
// 默认从session中获取
return Yii::$app->getSession()->get($this->csrfParam);
}
3. generateCsrfToken方法,生成令牌
//生成一个随机token
protected function generateCsrfToken()
{
// 32位token
$token = Yii::$app->getSecurity()->generateRandomString();
// 保存token到cookie或session
if ($this->enableCsrfCookie) {
// cookie对象
$cookie = $this->createCsrfCookie($token);
Yii::$app->getResponse()->getCookies()->add($cookie);
} else {
Yii::$app->getSession()->set($this->csrfParam, $token);
}
return $token;
}
4. getCsrfTokenFromHeader方法,从请求头获取令牌
// 从请求头中获取token
public function getCsrfTokenFromHeader()
{
return $this->headers->get(static::CSRF_HEADER);
}
5. createCsrfCookie方法,创建带有csrf令牌的cookie对象
// 生成cookie对象
protected function createCsrfCookie($token)
{
$options = $this->csrfCookie;
//返回cookie对象
return Yii::createObject(array_merge($options, [
'class' => 'yii\web\Cookie',
'name' => $this->csrfParam,
'value' => $token,
]));
}
6. validateCsrfToken方法,验证token
// csrf验证
public function validateCsrfToken($clientSuppliedToken = null)
{
$method = $this->getMethod();
// only validate CSRF token on non-"safe" methods https://tools.ietf.org/html/rfc2616#section-9.1.1
// 无需验证条件:
// 1. 未开启csrf验证
// 2. GET,HEAD,OPTIONS请求不验证
// 满足以上一个条件就可以
if (!$this->enableCsrfValidation
|| in_array($method, ['GET', 'HEAD', 'OPTIONS'], true)) {
return true;
}
// 掩码过的token
$trueToken = $this->getCsrfToken();
// 1. 用户提供的token
if ($clientSuppliedToken !== null) {
return $this->validateCsrfTokenInternal($clientSuppliedToken, $trueToken);
}
return
// 2. POST请求字段中携带的token
$this->validateCsrfTokenInternal($this->getBodyParam($this->csrfParam), $trueToken)
// 3. 请求头中携带的token
|| $this->validateCsrfTokenInternal($this->getCsrfTokenFromHeader(), $trueToken);
}
7. validateCsrfTokenInternal方法,token验证
// token验证
private function validateCsrfTokenInternal($clientSuppliedToken, $trueToken)
{
// 非字符串返回false
if (!is_string($clientSuppliedToken)) {
return false;
}
$security = Yii::$app->security;
//token比较
return $security->compareString(
$security->unmaskToken($clientSuppliedToken),
$security->unmaskToken($trueToken)
);
}
总结:
阅读了1个属性和7个方法:
- $_csrfToken 用于csrf验证的令牌
- getCsrfToken方法,返回csrf验证的token
- loadCsrfToken方法,从cookie或session获取令牌
- generateCsrfToken方法,生成令牌
- getCsrfTokenFromHeader方法,从请求头获取令牌
- createCsrfCookie方法,创建带有csrf令牌的cookie对象
- validateCsrfToken方法,验证token
- validateCsrfTokenInternal方法,token验证