>  기사  >  백엔드 개발  >  ThinkPHP에서 양식 토큰 오류 및 솔루션 분석

ThinkPHP에서 양식 토큰 오류 및 솔루션 분석

不言
不言원래의
2018-06-07 10:31:401897검색

이 글에서는 주로 ThinkPHP의 폼 토큰 오류와 해결 방법을 소개합니다. thinkPHP 폼 토큰의 원리, 구성, 오류 원인 및 해당 해결 방법을 자세히 분석합니다. 도움이 필요한 친구들이 참고할 수 있습니다. ThinkPHP의 오류 및 솔루션. 참고하실 수 있도록 자세한 내용을 공유합니다.

프로젝트 개발 과정에서 데이터를 추가하고 편집할 때 시스템에서 표시되는 "양식 토큰 오류"가 가끔 발생했습니다. 처음에는 QA에서 오늘 오후에 보고하기 전까지는 버그 시스템에 대한 언급이 있었는데, 우연히 시간이 좀 생겨서 TP3.13의 소스코드를 따라가서 읽어보니 알 수 있었습니다. 전체 이야기.

프로젝트에서 양식 토큰을 활성화하려면 일반적으로 구성 파일에서 다음 구성을 수행해야 합니다.

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

일반적으로 서버에 필드 필터링 규칙이 있는 모델이 있고 편집 데이터가 있습니다.

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

와 같은 데이터 감지 코드를 사용한 동작 이때 IDE에서 create()를 두 번 클릭하여 TP 프레임워크의 Model.class.php에서 create 메소드를 찾습니다

/**
* 创建数据对象 但不保存到数据库
* @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;
  }
  ……省略……
}

코드를 보면 autoCheckToken 메소드가 감지되는 시점을 이해할 수 있습니다. 실패하면 오류가 보고됩니다. 그런 다음 이 메소드를 계속 따르세요

// 自动表单令牌验证
// 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;
}

이 코드를 읽은 후 $_SESSION[ $name] 첫 번째 판단에서 이 Seesion 변수는 토큰을 생성할 때 시작되어야 하며 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;
}

이 코드는 주로 토큰을 생성하는 데 사용됩니다. TP가 양식 확인을 켤 때 현재 URI의 md5를 사용하고, 사용자가 양식을 제출하면 먼저 세션이 존재하는지 확인하고, 그렇지 않은 경우 양식 필드로 확인합니다. TOKEN_NAME이 일치하면 세션을 삭제하고(실제로 다음 번에 양식 명령 제출을 방지함) true를 반환하고, 그렇지 않으면 false를 반환합니다.

자, 주제로 돌아가서 TP

1에서 양식을 제출할 때 토큰 오류가 발생할 수 있는 가능성은 두 가지뿐입니다. 토큰이 켜져 있으면 제출된 양식 세션에 TOKEN_NAME 필드가 없거나 해당 필드가 없습니다. 현재 제출 양식 환경에서는 해당 세션이 생성되지 않습니다. 이는 주로 사용자가 제출한 후 사용자가 현재 페이지를 새로 고친 후 편집 페이지와 표시 페이지가 동일한 방식이기 때문입니다.

2. 세션 변수는 있지만 ​​전후 값이 다릅니다

저희 프로젝트에서 이런 오류가 발생하는 이유는 아래 구성을 보면 알 수 있습니다

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;
);

이렇게 작성했어야 합니다. 부울 값만큼 거짓이지만 어떤 영웅이 문자열로 거짓이라고 썼는지 알 수 없습니다. 그러면 물론 판단은 양식 토큰을 열고 프로젝트에서 추가, 편집 및 표시하는 논리에 따라 이루어집니다. 모두 동일한 방법입니다. 검증 오류가 발생하면 일반적인 프로그램 처리 로직은 원래 인터페이스로 돌아가며 이전과 동일합니다. 동일한 양식을 계속 제출하는 것은 반복 제출과 같습니다. , "양식 토큰 오류"가 보고됩니다.

관련 권장 사항:

thinkPHP에서 체크인 기능을 구현하는 방법


thinkphp는 Excel 데이터 가져오기 및 내보내기를 구현합니다(전체 케이스 첨부)


위 내용은 ThinkPHP에서 양식 토큰 오류 및 솔루션 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.