Использование первичного ключа / поля идентификатора в качестве идентификатора в URL - PullRequest
10 голосов
/ 19 февраля 2009

Каковы преимущества и недостатки использования первичного ключа базы данных в качестве идентификатора URL? Например, http://localhost/post/view/13 - 13 является моим основным ключом для таблицы сообщений.

Некоторые сайты, такие как reddit, используют, как я полагаю, уникальный идентификатор, который не является первичным ключом, но все же уникальным, чтобы помочь идентифицировать ссылку:

http://www.reddit.com/r/funny/comments/7ynin/the_mystery_of_irelands_worst_driver/

Вы можете изменить последнюю часть URL-адреса на любой другой, если / 7ynin / совпадает.


Похоже, что Digg использует кусок заголовка ссылки, чтобы идентифицировать ссылку:

http://digg.com/space/Liquid_Water_Recently_Seen_on_Mars

Хотя, если я правильно помню, установка WordPress по умолчанию использует index.php? P = # в качестве идентификатора до тех пор, пока не будут включены причудливые URL.


Я понимаю, почему ради SEO вы хотели бы иметь максимально информативный URL-адрес, но я просто пытаюсь понять, является ли использование первичного ключа угрозой безопасности или просто плохой формой.

Ответы [ 6 ]

14 голосов
/ 02 марта 2009

Вы всегда хотите подарить пользователю хороший URL-адрес, а не какой-нибудь неприятный автоматически сгенерированный идентификатор. Но я не думаю, что вы должны сделать указанный "дружественный URL" первичным ключом. Вы все равно должны использовать «классический» автоинкрементный числовой PK и иметь второй столбец, который является уникальным «дружественным URL». Почему?

  1. Все таблицы комментариев, рейтинги таблицы, любые таблицы, которые имеют отношения с вашей таблицей контента можно использовать числовой первичный ключ. Это означает, что меньшие индексы и ниже использование памяти.
  2. Кто-то захочет изменить дружественный URL. Если вы получил числовой первичный ключ, вы не должен обновить любой из ваших зависимых таблицы (или сделать это через БД каскадное обновление).
  3. В будущем Вы можете абстрагироваться от битов URL в другой стол. Указанная таблица может затем сохраните «устаревшие» сопоставления URL эта проблема перенаправляет на основной "реальная" карта URL. Затем, когда пользователь хочет изменить дружественный URL, Вы не должны сломать все входящие устаревшие URL. Не мог сделать это если ваш первичный ключ был "дружественный URL".
  4. Я бы по-прежнему был склонен использовать числовой первичный ключ во всех моих AJAX-сгущениях (например, функция javascript post_new_comment () будет принимать первичный ключ, а не какой-нибудь понятный URL). Единственный раз, когда я использую дружественный URL-адрес, - это любая структура URL-адреса, ориентированная на пользователя.
  5. Что касается безопасности? Если ваш контент контролируется доступом, вам придется проверять доступ независимо от того, является ли он первичным ключом или дружественным URL-адресом.
  6. Если вы разрешите способы доступа к контенту через первичный ключ, люди могут попробовать подключить случайные идентификаторы. Если ваше требование не только ограниченного доступа к контенту, но и отказа в указанном контенте существует, это вопрос формулировки ваших ошибок. Это то же самое, что и при сбое входа в систему - вы не говорите «имя пользователя не найдено», вы говорите «неверное имя пользователя или пароль». Вставка случайных значений для поиска контента будет проблемой для любого подхода, который вы используете, просто с числовыми ключами гораздо меньше значений, чтобы попробовать.

Итог: дружественные URL? Черт возьми да Используя их в качестве первичного ключа? Ад нет.

2 голосов
/ 20 февраля 2009

Если вы не включаете первичный ключ (и) в URL / ссылку, то вам нужно создать какой-то временный синтетический ключ, И затем вы должны сохранить отображение этот ключ в сеансе для пользователя. Это добавляет больше состояния / использования памяти / что-то, что может сломаться в вашем приложении.

Если значение действительно чувствительное, то может стоить стоимости его сокрытия. Однако затенение ключа на самом деле не делает его безопасным, не так ли? Вам нужно проверить роли пользователя в любом «контроллере» (сервлете, программном коде и т. Д.), Прежде чем предоставить доступ к элементу.

2 голосов
/ 19 февраля 2009

Как вы сказали, смысл помещать заголовки прямо в URL - это SEO. Наличие ключевых слов в URL-адресе оказывает значительное влияние на результаты поиска.

Однако, несколько других мыслей, связанных с вашими примерами:

  • Я не уверен, почему вы предполагаете, что буквенно-цифровой ключ reddit не является основным, нет ничего, что заставляет первичные ключи быть числовыми. Если это уникальный идентификатор сообщения, нет никаких причин не использовать его в качестве первичного ключа (или хотя бы его части).
  • Digg фактически обеспечивает уникальность названий (возможно, только внутри определенной категории, я не был в Digg несколько лет, поэтому не могу вспомнить). Я имел обыкновение видеть это довольно часто с дублирующейся историей, имеющей URL как:

    http://digg.com/space/Liquid_Water_Recently_Seen_on_Mars_2
    

    Это означает, что заголовок является, по крайней мере, частью первичного ключа, поскольку это единственный способ определить, к какому сюжету была предназначена ссылка.

На самом деле не существует значительного риска для безопасности при использовании первичного ключа в URL-адресе, кроме возможности для людей угадывать / предсказывать другие, как упоминалось в pantulis. Но вы все равно не должны полагаться на то, что «никто не догадается» в качестве меры безопасности.

2 голосов
/ 19 февраля 2009

По своей сути это не риск для безопасности, хотя он действительно рассказывает внешним лицам о вашей системе, чего обычно не следует делать.

1 голос
/ 23 января 2013

Reddit также использует числовой идентификатор, но конвертируется с использованием Base 36 , поэтому он отображается в виде строки. Это как шестнадцатеричное число, которое на самом деле тоже строка. Разница только в базе.

База 36 - это «самая компактная система буквенно-цифровых знаков без учета регистра, использующая символы ASCII», и она легко кодируется и декодируется. Почему 36? A-Z = 26 + 0-9 = 10.

1 голос
/ 19 февраля 2009

Недостаток: любой посетитель может легко попытаться угадать другие идентификаторы, которые могут быть не такими, как вы хотите.

...