When users log in to our website, we store some information in a session to retrieve it across the site. We created a few wrappers to help with data retrieval/storage to lessen duplication of code.
I'm trying to redesign it as I don't like how the UserModel is written. I believe it's dangerous with the static properties, but so far it's been working.
However...
While we haven't noticed any issues, recently someone use something very similar to our code (slightly modified) for another project and had about 20+ people log in at the same time. Some users saw other user's information instead of their own. This brought a huge concern on the original code (below) and would like to get any feedback on how to make it "better" or avoid the same issue they ran into (if it even will happen).
I searched/read around Google/Stack Overflow about the possible issue being at our static
method wrappers.
UserModel.cs
public class User {
private const Boolean UseSessionAsDataStore = true;
protected const String kUserId = "UserId";
protected const String kUserName = "UserName";
protected const String kUserEmail = "UserEmail";
public static Int32 UserId {
get { return GetInt32Value(kUserId); }
set { SaveValue(kUserId, value.ToString()); }
}
public static String UserName {
get { return GetStringValue(kUserName); }
set { SaveValue(kUserName, value); }
}
public static String UserEmail {
get { return GetStringValue(kUserEmail); }
set { SaveValue(kUserEmail, value); }
}
protected static void SaveValue(String key, String value) {
UseSessionAsDataStore ?
SessionHelper.SaveSessionValue(key, value) :
CookieHelper.SaveCookieValue(key, value);
}
protected static void GetStringValue(String key) {
UseSessionAsDataStore ? SessionHelper.GetSessionStringValue(key) : CookieHelper.GetCookieStringValue(key);
}
protected static void GetInt32Value(String key) {
UseSessionAsDataStore ? SessionHelper.GetSessionInt32Value(key) : CookieHelper.GetCookieInt32Value(key);
}
}
UserLoginModel.cs
public class UserLoginModel {
AssignUser (Int32 userId, String userName, String userEmail) {
UserModel.UserId = userId;
UserModel.UserName = userName;
UserModel.UserEmail = userEmail;
}
}
SessionHelper.cs
(won't provide CookieModel.cs as it's not the issue in question)
public class SessionHelper {
public static void SaveSessionValue(String key, String value) {
HttpContext.Current.Session.Add(key, value);
}
public static String GetSessionStringValue(String key) {
if (HttpContext.Current.Session == null || HttpContext.Current.Session[key] == null) { return null; }
return HttpContext.Current.Session[key] != null ? HttpContext.Current.Session[key].ToString() : String.Empty;
}
public static Int32 GetSessionInt32Value(String key) {
if (HttpContext.Current.Session == null || HttpContext.Current.Session[key] == null) { return 0; }
Int32 value;
Int32.TryParse(HttpContext.Current.Session[key].ToString(), out value);
return value;
}
}
LoginPage
/* try to log in user and return user data */
...
if (loginSuccessful) {
UserLoginModel.AssignUser(userId, userName, userEmail);
}
...
MainPage
<html>
<body>
Hello <%=UserModel.UserName %>!
</body>
</html>
...
I have a feeling that this code has the potential to share session data between 2 users, although we have yet to realize it, even with about 5 simultaneous logins.