Я хочу использовать файлы cookie для хранения идентификатора пользователя во время сеанса, что позволяет избежать ненужных обращений к базе данных.Этот userId используется для доступа к определенной пользовательской информации.Поскольку куки могут быть легко отредактированы, я теперь обеспокоен проблемой безопасности.
Чтобы запретить зарегистрированному пользователю редактировать свой userId и, таким образом, получать доступ к информации других пользователей, я использую довольно простой метод.Я добавляю еще один cookie-файл в момент создания cookie-файла userId, который хранит для него хеш-значение.При хешировании я использую жестко запрограммированную 64-байтовую клавишу.При извлечении userId из cookie-файла всегда проверяется, совпадает ли он с его хэшированным значением.
Вот мой код:
public static int GetUserId(Page page)
{
int userId;
if (page.Request.Cookies["userId"] != null && page.Request.Cookies["userIdHashed"] != null)
{
string userIdHashed = page.Request.Cookies["userIdHashed"].Value;
string userIdCoockie = page.Request.Cookies["userId"].Value;
string coockie = (userIdCoockie + "945AFF2FD0F1D89B4B1DBEB1B0C5D3B8B5DCE000AAEA331EB0C3F3A68C3865EFA73BC6EBF30C8DF1AD6B9ECB7094DA5B0C1AF36B5BBD096E3D873E9589E3F664").GetHashCode().ToString();
if (userIdHashed == coockie)
{
userId = Int32.Parse(userIdCoockie);
}
else
{
throw new Exception("UserId does not match!");
}
}
else
{
userId = ...//here userId is being retrieved from the data base and than:
page.Response.Cookies["userId"].Value = userId.ToString();
page.Response.Cookies["userId"].HttpOnly = true;
string userIdHashed = (userId.ToString() + "945AFF2FD0F1D89B4B1DBEB1B0C5D3B8B5DCE000AAEA331EB0C3F3A68C3865EFA73BC6EBF30C8DF1AD6B9ECB7094DA5B0C1AF36B5BBD096E3D873E9589E3F664").GetHashCode().ToString();
page.Response.Cookies["userIdHashed"].Value = userIdHashed;
page.Response.Cookies["userIdHashed"].HttpOnly = true;
}
return userId;
}
Итак, мои вопросы:
Может ли такой подход считаться достаточно надежным в этой ситуации?
Если нет, я должен изменить его и как или я должен искать что-то другое (например, шифрование /дешифрование с помощью System.Security.Cryptography в соответствии с рекомендациями здесь )?
И дополнительный вопрос: имеет ли смысл устанавливать HttpCookie.HttpOnly = true, чтобы запретить JavaScriptполучить доступ к куки-файлу, учитывая, что он также может быть легко изменен пользователем?
ОБНОВЛЕНИЕ
Большое спасибо за ответы Керреку С.Б. и Дарину Димитрову, которые разделяют мнение о том, что онНе имеет смысла пытаться защитить куки самостоятельно, учитывая, что уже существуют встроенные защищенные механизмы хранения такого рода информации между постбеками.
Предлагаются следующие варианты:
- Использование ASP.NET
cache
(но я считаю, что обычно предполагается хранить информацию, которая должна быть передана пользователям, поэтому я смотрю на другие дваoptions). - Добавление пользовательской строки с userId в часть UserData
FormsAuthenticationTicket
. - Использование
Session State
.
Так что в настоящее время явыбор между двумя последними.
Изменение FormsAuthenticationTicket не совсем просто.Кроме того, он не работает с аутентификацией форм без cookie (как указано здесь ).
Использовать состояние сеанса намного проще, но это может повлиять на производительность, поскольку он сохраняет значения в памяти сервера.Однако, может быть, в моем случае это не так драматично, потому что мы храним только userId типа int.
Так что на данный момент последний вариант выглядит намного лучше для меня.Однако я был бы очень признателен, если бы кто-то еще мог прокомментировать, поддержать или критиковать любой из обсуждаемых вариантов.
Заранее спасибо!