0

로드가 심할 때 내 사이트에 이상한 영향을 미칩니다.프로필 시스템 : 사용자가 동일한 ID를 공유

나는 임의로 다른 사용자 설정의 속성을 가져옵니다. 필자는 프로필 시스템을 자체적으로 구현 했으므로 프로필 시스템 자체를 비난 할 수는 없다고 생각합니다.

디버깅을 시작할 지점이 필요합니다. 나는 어딘가에 프로파일 엔트리에 매핑되는 쿠키 값이 있다고 생각한다. 이 매핑이 어떻게 작동하는지 볼 기회가 있습니까?

public ActionResult AddTyreToCart(CartViewModel model) 
    { 

     string profile = Request.IsAuthenticated ? Request.AnonymousID : User.Identity.Name; 

    } 

나는 디버깅 싶습니다 : 내가 컨트롤러에서 사용하는 방법

using System; 
using System.Text; 
using System.Configuration; 
using System.Web; 
using System.Web.Profile; 
using System.Collections; 
using System.Collections.Specialized; 
using B2CShop.Model; 
using log4net; 
using System.Collections.Generic; 
using System.Diagnostics; 
using B2CShop.DAL; 
using B2CShop.Model.RepositoryInterfaces; 
[assembly: log4net.Config.XmlConfigurator()] 
namespace B2CShop.Profile 
{ 
    public class B2CShopProfileProvider : ProfileProvider 
    { 
     private static readonly ILog _log = LogManager.GetLogger(typeof(B2CShopProfileProvider)); 
     // Get an instance of the Profile DAL using the ProfileDALFactory 
     private static readonly B2CShop.DAL.UserRepository dal = new B2CShop.DAL.UserRepository(); 
     // Private members 
     private const string ERR_INVALID_PARAMETER = "Invalid Profile parameter:"; 

     private const string PROFILE_USER = "User"; 
     private static string applicationName = B2CShop.Model.Configuration.ApplicationConfiguration.MembershipApplicationName; 

     /// <summary> 
     /// The name of the application using the custom profile provider. 
     /// </summary> 
     public override string ApplicationName 
     { 
      get 
      { 
       return applicationName; 
      } 
      set 
      { 
       applicationName = value; 
      } 
     } 


     /// <summary> 
     /// Initializes the provider. 
     /// </summary> 
     /// <param name="name">The friendly name of the provider.</param> 
     /// <param name="config">A collection of the name/value pairs representing the provider-specific attributes specified in the configuration for this provider.</param> 
     public override void Initialize(string name, NameValueCollection config) 
     { 
      if (config == null) 
       throw new ArgumentNullException("config"); 

      if (string.IsNullOrEmpty(config["description"])) 
      { 
       config.Remove("description"); 
       config.Add("description", "B2C Shop Custom Provider"); 
      } 

      if (string.IsNullOrEmpty(name)) 
       name = "b2c_shop"; 

      if (config["applicationName"] != null && !string.IsNullOrEmpty(config["applicationName"].Trim())) 
       applicationName = config["applicationName"]; 

      base.Initialize(name, config); 

     } 

     /// <summary> 
     /// Returns the collection of settings property values for the specified application instance and settings property group. 
     /// </summary> 
     /// <param name="context">A System.Configuration.SettingsContext describing the current application use.</param> 
     /// <param name="collection">A System.Configuration.SettingsPropertyCollection containing the settings property group whose values are to be retrieved.</param> 
     /// <returns>A System.Configuration.SettingsPropertyValueCollection containing the values for the specified settings property group.</returns> 
     public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection) 
     { 

      string username = (string)context["UserName"]; 
      bool isAuthenticated = (bool)context["IsAuthenticated"]; 
      //if (!isAuthenticated) return null; 
      int uniqueID = dal.GetUniqueID(username, isAuthenticated, false, ApplicationName); 



      SettingsPropertyValueCollection svc = new SettingsPropertyValueCollection(); 

      foreach (SettingsProperty prop in collection) 
      { 
       SettingsPropertyValue pv = new SettingsPropertyValue(prop); 

       switch (pv.Property.Name) 
       { 
        case PROFILE_USER: 
         if (!String.IsNullOrEmpty(username)) 
         { 
          pv.PropertyValue = GetUser(uniqueID); 
         } 
         break; 
        default: 
         throw new ApplicationException(ERR_INVALID_PARAMETER + " name."); 
       } 

       svc.Add(pv); 
      } 
      return svc; 
     } 


     /// <summary> 
     /// Sets the values of the specified group of property settings. 
     /// </summary> 
     /// <param name="context">A System.Configuration.SettingsContext describing the current application usage.</param> 
     /// <param name="collection">A System.Configuration.SettingsPropertyValueCollection representing the group of property settings to set.</param> 
     public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection) 
     { 

      string username = (string)context["UserName"]; 
      CheckUserName(username); 
      bool isAuthenticated = (bool)context["IsAuthenticated"]; 

      int uniqueID = dal.GetUniqueID(username, isAuthenticated, false, ApplicationName); 
      if (uniqueID == 0) 
      { 
       uniqueID = dal.CreateProfileForUser(username, isAuthenticated, ApplicationName); 
      } 

      foreach (SettingsPropertyValue pv in collection) 
      { 

       if (pv.PropertyValue != null) 
       { 
        switch (pv.Property.Name) 
        { 
         case PROFILE_USER: 
          SetUser(uniqueID, (UserInfo)pv.PropertyValue); 
          break; 
         default: 
          throw new ApplicationException(ERR_INVALID_PARAMETER + " name."); 
        } 
       } 
      } 

      UpdateActivityDates(username, false); 
     } 


     // Profile gettters 
     // Retrieve UserInfo 
     private static UserInfo GetUser(int userID) 
     { 
      return dal.GetUser(userID); 
     } 




     // Update account info 
     private static void SetUser(int uniqueID, UserInfo user) 
     { 
      user.UserID = uniqueID; 
      dal.SetUser(user); 
     } 


     // UpdateActivityDates 
     // Updates the LastActivityDate and LastUpdatedDate values 
     // when profile properties are accessed by the 
     // GetPropertyValues and SetPropertyValues methods. 
     // Passing true as the activityOnly parameter will update 
     // only the LastActivityDate. 
     private static void UpdateActivityDates(string username, bool activityOnly) 
     { 
      dal.UpdateActivityDates(username, activityOnly, applicationName); 
     } 

     /// <summary> 
     /// Deletes profile properties and information for the supplied list of profiles. 
     /// </summary> 
     /// <param name="profiles">A System.Web.Profile.ProfileInfoCollection of information about profiles that are to be deleted.</param> 
     /// <returns>The number of profiles deleted from the data source.</returns> 
     public override int DeleteProfiles(ProfileInfoCollection profiles) 
     { 

      int deleteCount = 0; 

      foreach (ProfileInfo p in profiles) 
       if (DeleteProfile(p.UserName)) 
        deleteCount++; 

      return deleteCount; 
     } 

     /// <summary> 
     /// Deletes profile properties and information for profiles that match the supplied list of user names. 
     /// </summary> 
     /// <param name="usernames">A string array of user names for profiles to be deleted.</param> 
     /// <returns>The number of profiles deleted from the data source.</returns> 
     public override int DeleteProfiles(string[] usernames) 
     { 

      int deleteCount = 0; 

      foreach (string user in usernames) 
       if (DeleteProfile(user)) 
        deleteCount++; 

      return deleteCount; 
     } 

     // DeleteProfile 
     // Deletes profile data from the database for the specified user name. 
     private static bool DeleteProfile(string username) 
     { 
      CheckUserName(username); 
      return dal.DeleteAnonymousProfile(username, applicationName); 
     } 

     // Verifies user name for sise and comma 
     private static void CheckUserName(string userName) 
     { 
      if (string.IsNullOrEmpty(userName) || userName.Length > 256 || userName.IndexOf(",") > 0) 
       throw new ApplicationException(ERR_INVALID_PARAMETER + " user name."); 
     } 

     /// <summary> 
     /// Deletes all user-profile data for profiles in which the last activity date occurred before the specified date. 
     /// </summary> 
     /// <param name="authenticationOption">One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are deleted.</param> 
     /// <param name="userInactiveSinceDate">A System.DateTime that identifies which user profiles are considered inactive. If the System.Web.Profile.ProfileInfo.LastActivityDate value of a user profile occurs on or before this date and time, the profile is considered inactive.</param> 
     /// <returns>The number of profiles deleted from the data source.</returns> 
     public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) 
     { 

      string[] userArray = new string[0]; 
      dal.GetInactiveProfiles((int)authenticationOption, userInactiveSinceDate, ApplicationName).CopyTo(userArray, 0); 

      return DeleteProfiles(userArray); 
     } 

     /// <summary> 
     /// Retrieves profile information for profiles in which the user name matches the specified user names. 
     /// </summary> 
     /// <param name="authenticationOption">One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned.</param> 
     /// <param name="usernameToMatch">The user name to search for.</param> 
     /// <param name="pageIndex">The index of the page of results to return.</param> 
     /// <param name="pageSize">The size of the page of results to return.</param> 
     /// <param name="totalRecords">When this method returns, contains the total number of profiles.</param> 
     /// <returns>A System.Web.Profile.ProfileInfoCollection containing user-profile information 
     //  for profiles where the user name matches the supplied usernameToMatch parameter.</returns> 
     public override ProfileInfoCollection FindProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords) 
     { 

      CheckParameters(pageIndex, pageSize); 

      return GetProfileInfo(authenticationOption, usernameToMatch, null, pageIndex, pageSize, out totalRecords); 
     } 

     /// <summary> 
     /// Retrieves profile information for profiles in which the last activity date occurred on or before the specified date and the user name matches the specified user name. 
     /// </summary> 
     /// <param name="authenticationOption">One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned.</param> 
     /// <param name="usernameToMatch">The user name to search for.</param> 
     /// <param name="userInactiveSinceDate">A System.DateTime that identifies which user profiles are considered inactive. If the System.Web.Profile.ProfileInfo.LastActivityDate value of a user profile occurs on or before this date and time, the profile is considered inactive.</param> 
     /// <param name="pageIndex">The index of the page of results to return.</param> 
     /// <param name="pageSize">The size of the page of results to return.</param> 
     /// <param name="totalRecords">When this method returns, contains the total number of profiles.</param> 
     /// <returns>A System.Web.Profile.ProfileInfoCollection containing user profile information for inactive profiles where the user name matches the supplied usernameToMatch parameter.</returns> 
     public override ProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) 
     { 

      CheckParameters(pageIndex, pageSize); 

      return GetProfileInfo(authenticationOption, usernameToMatch, userInactiveSinceDate, pageIndex, pageSize, out totalRecords); 
     } 

     /// <summary> 
     /// Retrieves user profile data for all profiles in the data source. 
     /// </summary> 
     /// <param name="authenticationOption">One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned.</param> 
     /// <param name="pageIndex">The index of the page of results to return.</param> 
     /// <param name="pageSize">The size of the page of results to return.</param> 
     /// <param name="totalRecords">When this method returns, contains the total number of profiles.</param> 
     /// <returns>A System.Web.Profile.ProfileInfoCollection containing user-profile information for all profiles in the data source.</returns>  
     public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords) 
     { 
      CheckParameters(pageIndex, pageSize); 

      return GetProfileInfo(authenticationOption, null, null, pageIndex, pageSize, out totalRecords); 
     } 

     /// <summary> 
     /// Retrieves user-profile data from the data source for profiles in which the last activity date occurred on or before the specified date. 
     /// </summary> 
     /// <param name="authenticationOption">One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned.</param> 
     /// <param name="userInactiveSinceDate">A System.DateTime that identifies which user profiles are considered inactive. If the System.Web.Profile.ProfileInfo.LastActivityDate of a user profile occurs on or before this date and time, the profile is considered inactive.</param> 
     /// <param name="pageIndex">The index of the page of results to return.</param> 
     /// <param name="pageSize">The size of the page of results to return.</param> 
     /// <param name="totalRecords">When this method returns, contains the total number of profiles.</param> 
     /// <returns>A System.Web.Profile.ProfileInfoCollection containing user-profile information about the inactive profiles.</returns> 
     public override ProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) 
     { 
      CheckParameters(pageIndex, pageSize); 

      return GetProfileInfo(authenticationOption, null, userInactiveSinceDate, pageIndex, pageSize, out totalRecords); 
     } 

     /// <summary> 
     /// Returns the number of profiles in which the last activity date occurred on or before the specified date. 
     /// </summary> 
     /// <param name="authenticationOption">One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned.</param> 
     /// <param name="userInactiveSinceDate">A System.DateTime that identifies which user profiles are considered inactive. If the System.Web.Profile.ProfileInfo.LastActivityDate of a user profile occurs on or before this date and time, the profile is considered inactive.</param> 
     /// <returns>The number of profiles in which the last activity date occurred on or before the specified date.</returns> 
     public override int GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate) 
     { 

      int inactiveProfiles = 0; 

      ProfileInfoCollection profiles = GetProfileInfo(authenticationOption, null, userInactiveSinceDate, 0, 0, out inactiveProfiles); 

      return inactiveProfiles; 
     } 

     //Verifies input parameters for page size and page index. 
     private static void CheckParameters(int pageIndex, int pageSize) 
     { 
      if (pageIndex < 1 || pageSize < 1) 
       throw new ApplicationException(ERR_INVALID_PARAMETER + " page index."); 
     } 

     //GetProfileInfo 
     //Retrieves a count of profiles and creates a 
     //ProfileInfoCollection from the profile data in the 
     //database. Called by GetAllProfiles, GetAllInactiveProfiles, 
     //FindProfilesByUserName, FindInactiveProfilesByUserName, 
     //and GetNumberOfInactiveProfiles. 
     //Specifying a pageIndex of 0 retrieves a count of the results only. 
     private static ProfileInfoCollection GetProfileInfo(ProfileAuthenticationOption authenticationOption, string usernameToMatch, object userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords) 
     { 

      ProfileInfoCollection profiles = new ProfileInfoCollection(); 

      totalRecords = 0; 

      // Count profiles only. 
      if (pageSize == 0) 
       return profiles; 

      int counter = 0; 
      int startIndex = pageSize * (pageIndex - 1); 
      int endIndex = startIndex + pageSize - 1; 

      DateTime dt = new DateTime(1900, 1, 1); 
      if (userInactiveSinceDate != null) 
       dt = (DateTime)userInactiveSinceDate; 

      /* 
      foreach(CustomProfileInfo profile in dal.GetProfileInfo((int)authenticationOption, usernameToMatch, dt, applicationName, out totalRecords)) { 
       if(counter >= startIndex) { 
        ProfileInfo p = new ProfileInfo(profile.UserName, profile.IsAnonymous, profile.LastActivityDate, profile.LastUpdatedDate, 0); 
        profiles.Add(p); 
       } 

       if(counter >= endIndex) { 
        break; 
       } 

       counter++; 
      } 
      */ 
      return profiles; 
     } 
    } 
} 

이것은 : 여기

내 프로필 공급자 얼마나 다른 쿠키를 제공하는 2 사용자가 얻을 수있는 같은 프로필?

편집 여기

는 getuniqueid

public int GetUniqueID(string userName, bool isAuthenticated, bool ignoreAuthenticationType, string appName) 
{ 

    SqlParameter[] parms = { 
      new SqlParameter("@Username", SqlDbType.VarChar, 256), 
      new SqlParameter("@ApplicationName", SqlDbType.VarChar, 256)}; 
    parms[0].Value = userName; 
    parms[1].Value = appName; 

    if (!ignoreAuthenticationType) 
    { 
    Array.Resize(ref parms, parms.Length + 1); 
    parms[2] = new SqlParameter("@IsAnonymous", SqlDbType.Bit) { Value = !isAuthenticated }; 
    } 

    int userID; 

    object retVal = null; 
    retVal = SqlHelper.ExecuteScalar(ConfigurationManager.ConnectionStrings["SQLOrderB2CConnString"].ConnectionString, CommandType.StoredProcedure, "getProfileUniqueID", parms); 

    if (retVal == null) 
    userID = CreateProfileForUser(userName, isAuthenticated, appName); 
    else 
    userID = Convert.ToInt32(retVal); 
    return userID; 
} 

코드입니다 그리고 이것은 SP입니다 :

CREATE PROCEDURE [dbo].[getProfileUniqueID] 

@Username VarChar(256), 
@ApplicationName VarChar(256), 
@IsAnonymous bit = null 
AS 
BEGIN 

    SET NOCOUNT ON; 
/* 
[getProfileUniqueID] 

created 
08.07.2009 mf 

Retrive unique id for current user 

*/ 
SELECT UniqueID FROM dbo.Profiles WHERE Username = @Username 
AND ApplicationName = @ApplicationName 
AND IsAnonymous = @IsAnonymous or @IsAnonymous = null 

END 
+0

당신은'dal.GetUniqueID (사용자 이름, IsAuthenticated는, 거짓, 가능 ApplicationName)의 소스를 게시 할 수;'? –

+0

@nick 게시판을 업데이트했습니다. –

답변

1

이 문제를 해결하기 위해 문제의 매우 어려운 유형이다. MVC가 아닌 ASP.NET 응용 프로그램에서도 비슷한 문제가 발생했습니다. 먼저 사용자를 식별 할 수있는 별도의 쿠키를 설정하여 ASP.NET 프로필 시스템을 완전히 우회하여 시작할 수 있다고 제안합니다. 그런 다음 해당 쿠키의 ID가 프로필의 ID와 일치하는지 확인할 수 있습니다. 그렇지 않으면 1) 사용자를 로그 아웃하여 다른 사람의 데이터에 액세스하지 못하게하고 2) 진단 정보를 수집 할 수 있습니다. 완전한 HTTP 요청 세부 정보가 시작됩니다. 그 패턴을 설정하지 않으면 사용자가 요청한 모든 HTTP 요청을 로깅하여 요청 기록에 문제가 재현되는 데 도움이되는 패턴이 있는지 확인할 수 있습니다.

우리의 경우 문제는 어리석은 가정 성장 캐싱 메커니즘이었습니다. 응용 프로그램은 ASP.NET에서 정적 파일 (예 : 이미지)을 캐시하려고 시도하고 쿠키가 캐시에 저장됩니다. 로드가 많은 경우 사용자는 다른 사용자의 쿠키로 이미지를로드하고 다른 사용자의 ID를 사용하는 경우가 있습니다. 귀하의 사례는 완전히 다를 수 있지만, 귀하가 찾는 유형의 단서를 제공 할 수 있습니다.

+0

당신의 이야기는 내가하는 일이 여기에 어떤 종류인지 보입니다. 다른 사용자 (다른 IP)가 동일한 쿠키 값을 얻는 것을 보았습니다 .ASPXANONYMOUS. 나는 "FormsAuthentication"에 대해 물어 보는 새로운 질문을 열 것입니다. –

0

주어진 소스는 괜찮은 것처럼 보이지만 모든 해당 소스 코드 (예 : B2CShop.DAL.UserRepository 클래스의 모든 사용 된 메소드)가 없을 경우에는 중대한 선언을 할 수 없습니다. 데이터베이스 스키마 일 수도 있습니다.

먼저 데이터베이스의 데이터가 손상되었는지 확인하여 일부 사용자가 동일한 고유 ID 또는 동일한 사용자 이름/응용 프로그램/isanonymous 조합을 소유하고 있다고 말할 수 있습니다. uniqueid가 기본 키인 경우 제외 할 수 있습니다.

1

나는 이것을 깊이 보지 않았지만, 한 가지가 나에게 뛰어 들었다.당신의 where 절 변화에

당신은 무엇을 @IsAnonymous가 null의 경우 일이하고 싶어

@IsAnonymous = null 

@IsAnonymous IS NULL 

에? where 절에 몇 개의 괄호를 추가해야 할 수도 있습니다.

SELECT UniqueID FROM dbo.Profiles 
WHERE Username = @Username 
    AND ApplicationName = @ApplicationName 
    AND (IsAnonymous = @IsAnonymous OR @IsAnonymous IS NULL) 

동일한 프로필 데이터를받은 두 명의 사용자가 있습니까? 그렇다면 거기에서 시작하십시오. 먼저 저장된 proc을 통해 그들을 실행할 것입니다. 쉽고 빠르게 할 수 있습니다. 문제의 이러한 종류의 ... 난이 원인으로 다음과 같은 본 일어날 때마다

0

...

  1. 캐시
  2. 정적 변수

당신이 코드를 작성하려고 할 수 정적 변수없이 문제가 해결되는지 확인하십시오.

안부, 라훌

관련 문제