Тип Безопасное Кодирование - PullRequest
2 голосов
/ 24 ноября 2010

Когда я начал разрабатывать веб-приложения, я сохранял данные аутентификации пользователя в двух переменных сеанса

 Session["UserName"]="username";
 Session["Password"]="paswword-123";

Но кто-то предложил мне идею создать класс, который бы содержал свойства UserName и Password и был бы успешным.Аутентификация Меня попросили создать экземпляр класса, задать свойства UserName и Password и сохранить этот экземпляр в сеансе.

Мне сказали, что объектом сеанса является TypeSafe.Может кто-нибудь объяснить, что такое безопасное кодирование и преимущество хранения объекта в сеансе.

Ответы [ 3 ]

6 голосов
/ 24 ноября 2010

По сути, классический подход к хранению значений непосредственно в Session["something"] имеет два недостатка:

  • Волшебные строки : если вы набрали something, ваш код компилируется нормально, новы получаете либо ошибку времени выполнения, либо, что еще хуже, незаметную ошибку в вашем коде.
  • Приведение : После прочтения Session["something"] вам необходимо привести его к нужному вам типу.(Это то, что подразумевается под «не типобезопасным» .)

Использование строго типизированного объекта, хранящегося в сеансе, устранило вторую проблему.Ну, на самом деле, ваш пользовательский объект все еще нуждается в приведении, но это только одно приведение вместо двух (или десяти) приведений, что снижает вероятность того, что что-то пойдет не так.Опять же, неправильное приведение - это то, что обнаруживается только во время выполнения.

Другой подход заключается в инкапсуляции доступа к переменным Session в статических свойствах:

public class MySession {
    public static string UserName {
        get { return (string)HttpContext.Current.Session["UserName"]; }
        set { HttpContext.Current.Session["UserName"] = value; }
    }
}

Конечно, оба подходаможно комбинировать, позволяя группировать связанные свойства (имя пользователя и пароль) в общий объект.

3 голосов
/ 24 ноября 2010

Наличие класса User с 2 полями может быть полезным по многим причинам, например, для безопасности типов, если вы когда-нибудь введете Session ["Pasword"] где-нибудь, вы получите ошибку, которую не так легко найти, вам придется везде проверьте оба имени параметра. Вам нужно, чтобы они были правильными, и это большой источник ошибок. После того, как вы сохраните объект User вместо 2 неподключенных строк, вы сможете использовать безопасный код типа, такой как User.Password, вместо того, чтобы пытаться получить доступ к паролю с помощью индексатора строк в Session. Также, если ваш пользователь когда-либо получит больше полей, что является очень распространенным явлением, вы просто добавите их в класс User, а не начнете создавать новые параметры и имена и сохраните их в куче сеанса.

Что касается типобезопасного кодирования, я думаю, что http://en.wikipedia.org/wiki/Type_safety должно помочь, или любой другой тип статьи на тему, которая очень популярна, я думаю.

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

0 голосов
/ 24 ноября 2010

Ну, ты друг наполовину прав, но я не верю, что сессия по своей сути безопасна.Коллекция Session хранит экземпляры объекта.Таким образом, вы можете хранить экземпляр любого типа (строку, int или пользовательский класс входа в систему), поскольку все они являются производными от объекта.Однако, когда вы извлекаете этот объект, вы не знаете, что это за тип, и вам нужно тщательно привести его, с обработкой исключений, прежде чем использовать его.например, это работает нормально:

Session["UserName"] = "Freddy";
string theUserName = (string)Session["UserName"];

Однако вы можете попытаться сделать следующее, что приведет к ошибкам.

Session["UserName"] new StrangeDataClass(); //Uh Oh, that's not a string.
string theUserName = (string)Session["UserName"]; //unexpected behaviour based on StrangeDataClass.ToString() implementation.

Чтобы обойти это, вам нужно будет сделать следующее:

string theUserName = Session["UserName"] as string;
if (string != null)
    //The cast worked...
else
    //The cast failed, (or the string stored in session was null)

Наличие пользовательского объекта входа в систему немного решает эту проблему, потому что у вас будет только один объект для беспокойства и один объект приведения.Вы также можете легко расширить объект входа в систему с помощью дополнительной информации, и при этом вам больше не придется выполнять приведения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...