TokenBuildBehavior.class.php 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | TOPThink [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2010 http://topthink.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. namespace Behavior;
  12. /**
  13. * 系统行为扩展:表单令牌生成
  14. */
  15. class TokenBuildBehavior
  16. {
  17. public function run(&$content)
  18. {
  19. if (C('TOKEN_ON')) {
  20. list($tokenName, $tokenKey, $tokenValue) = $this->getToken();
  21. $input_token = '<input type="hidden" name="' . $tokenName . '" value="' . $tokenKey . '_' . $tokenValue . '" />';
  22. $meta_token = '<meta name="' . $tokenName . '" content="' . $tokenKey . '_' . $tokenValue . '" />';
  23. if (strpos($content, '{__TOKEN__}')) {
  24. // 指定表单令牌隐藏域位置
  25. $content = str_replace('{__TOKEN__}', $input_token, $content);
  26. } elseif (preg_match('/<\/form(\s*)>/is', $content, $match)) {
  27. // 智能生成表单令牌隐藏域
  28. $content = str_replace($match[0], $input_token . $match[0], $content);
  29. }
  30. $content = str_ireplace('</head>', $meta_token . '</head>', $content);
  31. } else {
  32. $content = str_replace('{__TOKEN__}', '', $content);
  33. }
  34. }
  35. //获得token
  36. private function getToken()
  37. {
  38. $tokenName = C('TOKEN_NAME', null, '__hash__');
  39. $tokenType = C('TOKEN_TYPE', null, 'md5');
  40. if (!isset($_SESSION[$tokenName])) {
  41. $_SESSION[$tokenName] = array();
  42. }
  43. // 标识当前页面唯一性
  44. $tokenKey = md5($_SERVER['REQUEST_URI']);
  45. if (isset($_SESSION[$tokenName][$tokenKey])) {
  46. // 相同页面不重复生成session
  47. $tokenValue = $_SESSION[$tokenName][$tokenKey];
  48. } else {
  49. $tokenValue = is_callable($tokenType) ? $tokenType(microtime(true)) : md5(microtime(true));
  50. $_SESSION[$tokenName][$tokenKey] = $tokenValue;
  51. if (IS_AJAX && C('TOKEN_RESET', null, true)) {
  52. header($tokenName . ': ' . $tokenKey . '_' . $tokenValue);
  53. }
  54. //ajax需要获得这个header并替换页面中meta中的token值
  55. }
  56. return array($tokenName, $tokenKey, $tokenValue);
  57. }
  58. }