Где хранить зарегистрированные данные пользователя в ASP.NET MVC с использованием проверки подлинности с помощью форм?
Я использую ASP.NET MVC и Forms Authentication в своем приложении. В основном я использую FormsAuthentication.SetAuthCookie
для входа в систему и FormsAuthentication.SignOut
для выхода из системы.
В HttpContext.Current.User.Identity я сохранил имя пользователя, но мне нужна дополнительная информация о зарегистрированном пользователе. Я не хочу хранить весь пользовательский объект в сеансе, потому что он может быть большим и с гораздо большей информацией, чем мне нужно.
Считаете ли вы хорошей идеей создать класс класса LoggedUserInfo
только с теми атрибутами, которые мне нужны, а затем добавить его в сеанс variable
? Это хороший подход?
Или у вас есть лучшие идеи?
Ответы
Ответ 1
Я использую это решение:
ASP.NET 2.0 Аутентификация форм - Сохранение ее настройки еще простой
Подводя итог: я создал свою собственную реализацию IPrincipal. Он хранится в HttpContext.Current.Cache. Если он каким-то образом потерян, у меня есть имя пользователя из файла cookie авторизации на стороне клиента и его можно восстановить. Это решение не полагается на сеанс, который можно легко потерять.
ИЗМЕНИТЬ
Если вы хотите использовать своего принципала в своем контроллере и сделать его проверяемым, вы можете сделать это:
private MyPrincipal _myPrincipal;
MyPrincipal MyPrincipal
{
get
{
if (_myPrincipal == null)
return (MyPrincipal)User;
return _myPrincipal;
}
set
{
_myPrincipal = value;
}
}
В вашем тесте вы установите объект, подготовленный для тестирования. В противном случае он будет взят из HttpContext. И теперь я начал думать, почему я использую Ninject для этого?
Ответ 2
Мне действительно нравится использовать CustomPrincipal и CustomIdentity, которые я установил в методе действия входа в систему, например
if (!String.IsNullOrEmpty(username) && !String.IsNullOrEmpty(password) && _authService.IsValidLogin(username, password))
{
User objUser = _userService.GetUserByName(username);
if (objUser != null)
{
//** Construct the userdata string
string userData = objUser.RoleName + "|" + objUser.DistrictID + "|" + objUser.DistrictName + "|" + objUser.ID + "|" + objUser.DisplayName;
HttpCookie authCookie = FormsAuthentication.GetAuthCookie(username, rememberMe.GetValueOrDefault());
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
FormsAuthenticationTicket newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, userData);
authCookie.Value = FormsAuthentication.Encrypt(newTicket);
Response.Cookies.Add(authCookie);
return RedirectToAction("Index", "Absence");
}
else
{
return RedirectToAction("LogOn", "Account");
}
}
else
{
return RedirectToAction("LogOn", "Account");
}
Затем в пользовательском принципе вы можете иметь методы, которые обращаются к конкретной информации, которую вы передали конструктору типа
((CustomIdentity)((CustomPrincipal)HttpContext.Current.User).Identity).DisplayName;
где свойство DisplayName объявлено в классе CustomIdentity.
Ответ 3
Храните его на стороне сервера в сеансе.
Eg.
// Make this as light as possible and store only what you need
public class UserCedentials
{
public string Username { get; set; }
public string SomeOtherInfo { get; set; }
// etc...
}
Затем, когда они регистрируются, просто выполните следующие действия, чтобы сохранить информацию о пользователях:
// Should make typesafe accessors for your session objects but you will
// get the point from this example
Session["UserCredentials"] = new UserCredentials()
{ Username = "SomeUserName", SomeOtherInfo = "SomeMoreData" };
Затем, когда вам это нужно, выберите его:
UserCredentials user = (UserCredentials)(Session["UserCredentials"]);
Я написал пару вопросов/ответов о выполнении пользовательской авторизации в MVC:
Как выполнить проверки авторизации в ASP.NET MVC на основе данных сеанса?
Как работает тег авторизации? - Asp.net Mvc
Ответ 4
Хорошо, вам придется их хранить. Два основных возможных места:
Сервер
Вы можете поместить их в сеанс. Я предлагаю вам создать отдельный класс, который будет содержать только данные, которые вам действительно нужны, чтобы не тратить слишком много памяти. Или вы также можете хранить в кеше, который может в итоге иметь много вызовов БД, когда есть огромное количество одновременных пользователей.
Клиент
В этом случае, если вы можете ограничить объем данных отдельным классом, к этому и использовать любой способ его сериализации и отправить его клиенту. Либо в cookie, либо в URI (если разрешены длины и файлы cookie отключены)...
Результат этих мыслей:
главное здесь было бы создать отдельный класс, если вы приобретете много ресурсов памяти таким образом. Итак, первое, что вы должны сделать.