【问题标题】:modifying url shortner script修改 url 更短的脚本
【发布时间】:2011-07-30 03:01:33
【问题描述】:

我一直在使用Johnboy URL shortner,我注意到它不会检查它生成的 URL 是否存在于数据库中。如何确保 URL 是唯一的>

【问题讨论】:

  • 您可以在 INSERT 查询之前检查数据库中的 URL。不过,考虑到它甚至不检查缩短的 URL 是否已在使用中,我会使用更好的脚本。
  • @ceejayoz:这不是这个问题的目的吗?
  • 确保修改脚本以防止 XSS:johnboy.me/?s=%22%3E%3C/a%3E%3Cimg%20src=%22http://…
  • 实际上,它确实会检查 URL 是否已经缩短。我说的是缩短的 URL,顺便说一句 - 就像随机的 5 字符字符串。
  • @Tomalak 没有迹象表明他尝试过什么或他的技术知识,很难说。

标签: php mysql short-url


【解决方案1】:

只需将UNIQUE 添加到数据库列url_link 即可。

【讨论】:

  • $short = substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'), 0, 5); mysql_query("INSERT INTO urls (url_link, url_short, url_ip, url_date) VALUES ('".addslashes($_POST['url'])."', '".$short."', '".$_SERVER[' REMOTE_ADDR']."', '".time()."' ) ");我把它放在哪里?
  • db.php 中的PRIMARY KEY (`url_id`) 之后添加, UNIQUE KEY (`url_link`)
  • 既然我这样做了,如果密钥存在会发生什么?
【解决方案2】:

为长 URL 或短 URL 或两者创建一个 unique index/constraint。当脚本尝试插入具有相同值的另一条记录时,INSERT 语句将失败并返回 specific error code,您可以对其进行测试和适当处理。

define('MYSQL_ER_DUP_ENTRY', 1062);
...
if ( !mysql_query($mysql, $query) ) {
  if ( MYSQL_ER_DUP_ENTRY==mysql_errno($mysql) ) {
    // handle duplicate entry
  }
}

【讨论】:

    【解决方案3】:

    您可以使用外键约束来确保数据库级别的唯一网址。然后,在 php 中,检查查询是否插入了一行 - 如果是,那么你知道一个唯一的 url 已经被插入,如果没有,那么给用户或脚本一个机会用一个新的字符串再试一次。

    【讨论】:

      【解决方案4】:

      似乎 johnboy 的脚本充满了漏洞……但是你去吧! (修改 index.php 脚本,计算新的短 url)

      $short = substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'), 0, 5); 
      $unique = false;
      while(!$unique) {
          $exists = mysql_fetch_assoc(mysql_query("SELECT url_link FROM urls WHERE url_short = '".$short."'")); 
          if($exists['url_link'] != '') {
              // one already exists! create another, try again.
              $short = substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'), 0, 5); 
          } else {
              $unique = true;
          }
      }
      mysql_query("INSERT INTO urls (url_link, url_short, url_ip, url_date) VALUES 
          ( 
          '".addslashes($_POST['url'])."', 
          '".$short."', 
          '".$_SERVER['REMOTE_ADDR']."', 
          '".time()."' 
          ) 
      "); 
      

      【讨论】:

      【解决方案5】:

      DB 表如下所示:

      CREATE TABLE IF NOT EXISTS `urls` (
        `url_id` int(11) NOT NULL auto_increment,
        `url_link` varchar(255) default NULL,
        `url_short` varchar(6) default NULL,
        `url_date` int(10) default NULL,
        `url_ip` varchar(255) default NULL,
        `url_hits` int(11) default '0',
        PRIMARY KEY  (`url_id`)
      ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
      

      主键是一个自动递增的整数,不会在应用程序的任何地方使用。您可以摆脱它并使用url_short 作为主键。然后,您可以在插入新内容时执行以下三件事之一:

      1. 使用INSERT IGNORE 并默默地丢弃骗子。
      2. 使用INSERT ... ON DUPLICATE KEY UPDATE ... 并更新骗子。
      3. 使用普通的INSERT并检查错误代码:如果是1062,那就是骗子。

      我会选择#3。

      但是,考虑到它使用addslashes() 将输入参数注入 SQL,我将完全避免使用此脚本。它看起来过时且不安全。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-16
        • 2014-06-13
        • 2015-04-26
        • 1970-01-01
        • 2012-09-25
        • 2020-01-20
        相关资源
        最近更新 更多