Heim >Backend-Entwicklung >PHP-Tutorial >Analyse und Behebung von Formular-Token-Fehlern unter ThinkPHP

Analyse und Behebung von Formular-Token-Fehlern unter ThinkPHP

*文
*文Original
2018-01-03 11:45:211845Durchsuche

Wie behebt man den Formular-Token-Fehler unter ThinkPHP? In diesem Artikel werden hauptsächlich Form-Token-Fehler und -Lösungen unter ThinkPHP vorgestellt und die Prinzipien, Konfigurationen, Fehlerursachen und entsprechenden Lösungen von thinkPHP-Form-Tokens detaillierter analysiert. Freunde in Not können darauf verweisen. Ich hoffe, dass es für alle hilfreich ist.

Die Details sind wie folgt:

Während des Entwicklungsprozesses des Projekts ist mir beim Hinzufügen und Bearbeiten von Daten, die ich nicht bezahlt habe, gelegentlich der „Formular-Token-Fehler“ aufgefallen Anfangs war ihm viel Aufmerksamkeit geschenkt, bis der Qualitätssicherungsdienst heute Nachmittag dem Fehlersystem gegenüber etwas Freizeit hatte, also folgte er dem Quellcode von TP3.13 und las ihn nach ein paar Minuten ganze Geschichte.

Um Formular-Tokens im Projekt zu aktivieren, müssen Sie normalerweise die folgende Konfiguration in der Konfigurationsdatei vornehmen

// 是否开启令牌验证
'TOKEN_ON' => true,
// 令牌验证的表单隐藏字段名称
'TOKEN_NAME' => '__hash__',
//令牌哈希验证规则 默认为MD5
'TOKEN_TYPE' => 'md5',
//令牌验证出错后是否重置令牌 默认为true
'TOKEN_RESET' => true

Nehmen Sie Bearbeitungsdaten als Beispiel. Normalerweise gibt es ein Modell auf dem Server Seite mit darauf geschriebenen Feldfilterregeln. Die Aktion schreibt den Datenerkennungscode, z. B.

$table = D('table');
if(!$table->create()){
  exit($this->error($table->getError()));
}

. Doppelklicken Sie dann in der IDE auf create(), um die Erstellungsmethode

/**
* 创建数据对象 但不保存到数据库
* @access public
* @param mixed $data 创建数据
* @param string $type 状态
* @return mixed
*/
public function create($data='',$type='') {
  ……省略……
  // 表单令牌验证
  if(!$this->autoCheckToken($data)) {
    $this->error = L('_TOKEN_ERROR_');
    return false;
  }
  ……省略……
}
Wenn Sie den Code sehen, werden Sie verstehen, dass ein Fehler gemeldet wird, wenn die Methode autoCheckToken nicht erkannt wird, und diese Methode dann weiter verfolgen


// 自动表单令牌验证
// TODO ajax无刷新多次提交暂不能满足
public function autoCheckToken($data) {
  // 支持使用token(false) 关闭令牌验证
  // 如果在Action写了D方法,但没有对应的Model文件,那么$this->options为空
  if(isset($this->options['token']) && !$this->options['token']) return true;
  if(C('TOKEN_ON')){
    $name  = C('TOKEN_NAME');
    if(!isset($data[$name]) || !isset($_SESSION[$name])) { // 令牌数据无效
      return false;
    }
    // 令牌验证
    list($key,$value) = explode('_',$data[$name]);
    if($value && $_SESSION[$name][$key] === $value) { // 防止重复提交
      unset($_SESSION[$name][$key]); // 验证完成销毁session
      return true;
    }
    // 开启TOKEN重置
    if(C('TOKEN_RESET')) unset($_SESSION[$name][$key]);
    return false;
  }
  return true;
}
Nachdem Sie diesen Code gelesen haben, werden Sie feststellen, dass das Urteil $_SESSION[$name] enthält. Woher kommt also diese Seesionsvariable? Dies muss beim Generieren des Tokens beginnen die Datei TokenBuildBehavior.class.php


// 创建表单令牌
private function buildToken() {
  $tokenName = C('TOKEN_NAME');
  $tokenType = C('TOKEN_TYPE');
  if(!isset($_SESSION[$tokenName])) {
    $_SESSION[$tokenName] = array();
  }
  // 标识当前页面唯一性
  $tokenKey  = md5($_SERVER['REQUEST_URI']);
  if(isset($_SESSION[$tokenName][$tokenKey])) {// 相同页面不重复生成session
    $tokenValue = $_SESSION[$tokenName][$tokenKey];
  }else{
    $tokenValue = $tokenType(microtime(TRUE));
    $_SESSION[$tokenName][$tokenKey]  = $tokenValue;
  }
  $token   = &#39;<input type="hidden" name="&#39;.$tokenName.&#39;" value="&#39;.$tokenKey.&#39;_&#39;.$tokenValue.&#39;" />&#39;;
  return $token;
}
Dieser Code wird hauptsächlich zum Generieren eines Tokenwerts unter Verwendung von TOKEN_NAME und dem MD5 des aktuellen URI verwendet, wenn TP die Formularüberprüfung aktiviert, wenn der Benutzer das übermittelt Wenn nicht, wird „false“ zurückgegeben. Wenn dies der Fall ist, wird die Sitzung zuerst gelöscht (um zu vermeiden, dass der Formular-Token-Fehler beim nächsten Mal gesendet wird). Geben Sie true zurück, andernfalls geben Sie false zurück.


ok, zurück zum Thema, es gibt nur zwei Möglichkeiten für Token-Fehler bei der Formularübermittlung unter TP

1 Senden mit aktiviertem Token. Im Formular gibt es keinen TOKEN_NAME Feld oder keine entsprechende Sitzung (in der aktuellen Übermittlungsformularumgebung wird keine entsprechende Sitzung generiert. Dies liegt hauptsächlich daran, dass nach dem Absenden durch den Benutzer ein Fehler gemeldet wird und der Benutzer dann die aktuelle Seite aktualisiert. Gleichzeitig werden die Bearbeitungsseite und die Anzeigeseite sind in der gleichen Methode)

2. Es gibt eine Sitzungsvariable, aber die Vorher- und Nachherwerte sind unterschiedlich

Der Grund, warum dieser Fehler in unserem Projekt auftritt, können Sie finden Schauen Sie sich die folgende Konfiguration an

return array (
  &#39;TOKEN_ON&#39; => &#39;false&#39;,
  &#39;TOKEN_NAME&#39; => &#39;__hash__&#39;,
  &#39;TOKEN_TYPE&#39; => &#39;md5&#39;,
  &#39;TOKEN_RESET&#39; => &#39;true&#39;,
  &#39;DB_FIELDTYPE_CHECK&#39; => &#39;true&#39;
);
Es sollte sein: Wenn false als boolescher Wert geschrieben wird, weiß ich nicht, welcher Held ihn so geschrieben hat, dass er als Zeichenfolge falsch ist. Dann wird das Urteil natürlich basieren In Bezug auf die Logik des Öffnens des Formular-Tokens sind das Hinzufügen, Bearbeiten und Anzeigen im Projekt alle dieselben Methoden. Sobald ein Überprüfungsfehler auftritt, kehrt die allgemeine Programmverarbeitungslogik zur ursprünglichen Schnittstelle zurück und es handelt sich um dasselbe Formular Wie beim letzten Mal entspricht die kontinuierliche Übermittlung desselben Formulars einer wiederholten Übermittlung, dann wird ein „Formular-Token-Fehler“ gemeldet.


Verwandte Empfehlungen:

Detaillierte Erläuterung der Verhaltenserweiterungen und Plug-ins von ThinkPHP

Detaillierte Erklärung, wie ThinkPHP Verifizierungscodes generiert und überprüft

Detaillierte Erklärung der thinkphp5-URL und Routing-Funktionen mit Beispielen

Das obige ist der detaillierte Inhalt vonAnalyse und Behebung von Formular-Token-Fehlern unter ThinkPHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn