이 글에서는 주로 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 = '<input type="hidden" name="'.$tokenName.'" value="'.$tokenKey.'_'.$tokenValue.'" />'; return $token; }
이 코드는 주로 토큰을 생성하는 데 사용됩니다. TP가 양식 확인을 켤 때 현재 URI의 md5를 사용하고, 사용자가 양식을 제출하면 먼저 세션이 존재하는지 확인하고, 그렇지 않은 경우 양식 필드로 확인합니다. TOKEN_NAME이 일치하면 세션을 삭제하고(실제로 다음 번에 양식 명령 제출을 방지함) true를 반환하고, 그렇지 않으면 false를 반환합니다.
자, 주제로 돌아가서 TP
1에서 양식을 제출할 때 토큰 오류가 발생할 수 있는 가능성은 두 가지뿐입니다. 토큰이 켜져 있으면 제출된 양식 세션에 TOKEN_NAME 필드가 없거나 해당 필드가 없습니다. 현재 제출 양식 환경에서는 해당 세션이 생성되지 않습니다. 이는 주로 사용자가 제출한 후 사용자가 현재 페이지를 새로 고친 후 편집 페이지와 표시 페이지가 동일한 방식이기 때문입니다.
2. 세션 변수는 있지만 전후 값이 다릅니다
저희 프로젝트에서 이런 오류가 발생하는 이유는 아래 구성을 보면 알 수 있습니다
return array ( 'TOKEN_ON' => 'false', 'TOKEN_NAME' => '__hash__', 'TOKEN_TYPE' => 'md5', 'TOKEN_RESET' => 'true', 'DB_FIELDTYPE_CHECK' => 'true' );
이렇게 작성했어야 합니다. 부울 값만큼 거짓이지만 어떤 영웅이 문자열로 거짓이라고 썼는지 알 수 없습니다. 그러면 물론 판단은 양식 토큰을 열고 프로젝트에서 추가, 편집 및 표시하는 논리에 따라 이루어집니다. 모두 동일한 방법입니다. 검증 오류가 발생하면 일반적인 프로그램 처리 로직은 원래 인터페이스로 돌아가며 이전과 동일합니다. 동일한 양식을 계속 제출하는 것은 반복 제출과 같습니다. , "양식 토큰 오류"가 보고됩니다.
관련 권장 사항:
thinkPHP에서 체크인 기능을 구현하는 방법 thinkphp는 Excel 데이터 가져오기 및 내보내기를 구현합니다(전체 케이스 첨부)위 내용은 ThinkPHP에서 양식 토큰 오류 및 솔루션 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!