سؤال

كيف يمكنني حفظ شيء ما باستخدام FormsAuthentication؟ لا أريد تخزين userD من خلال عنوان URL.

على سبيل المثال ، لدي الآن هذا الرمز:

//UserController class:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
  if (repository.ValidateUser(model.Login, model.Password))
  {
    FormsAuthentication.SetAuthCookie(model.Login, model.RememberMe);
    if (Url.IsLocalUrl(returnUrl))
    {
      return Redirect(returnUrl);
    }
    else
    {
      return RedirectToAction("Project", "Index");
    }
  }
  else
  {
     ModelState.AddModelError("", "Incorrect name or password.");
  }
}

return View(model);
}

ProjectController صف دراسي:

public ViewResult Index()
{
    return View(repository.GetUserProjects(
        this.ControllerContext.HttpContext.User.Identity.Name));
}

ProjectRepository:

ProjectsContext context = new ProjectsContext();
UsersContext uCnt = new UsersContext();

public IEnumerable<Project> GetUserProjects(String username)
{
    if (String.IsNullOrEmpty(username))
        throw new ArgumentNullException("username", "Login is empty");
    return this.uCnt.Users
               .FirstOrDefault(u => u.Login == username)
               .Projects
               .ToList();
}

لا يبدو ProjectController و ProjectRepository مثل رمز جيد ... ربما يمكن لشخص ما تقديم المشورة ، وكيفية تخزين UserD دون استخدام عنوان URL؟ أفضل طريقة للقيام بذلك هي حفظ معرفات على التلقائي ، على ما أعتقد. لم أجد أي خصائص في User.identity للقيام بذلك ...

UPD

أتوسل إلى العفو ، لكنني نسيت أن أقول إنني أستخدم MVC-3 مع عرض الحلاقة. وهذا UserD ليس سلسلة (user.ident.name هو سلسلة) يمكن أن يكون GUID أو ربما كائني الخاص ...

هل كانت مفيدة؟

المحلول

احفظ معرف المستخدم في خاصية userData لتذكرة FormsAuthentication في ملف تعريف الارتباط عند تسجيل الدخول: يقوم المستخدم بتسجيل الدخول:

string userData = userID.ToString();

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, user.Email,
    DateTime.Now, DateTime.Now.AddMinutes(FormsAuthentication.Timeout.TotalMinutes),
    createPersistentCookie, userData);
string hashedTicket = FormsAuthentication.Encrypt(ticket);

HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashedTicket);
HttpContext.Current.Response.Cookies.Add(cookie);

يمكنك قراءتها مرة أخرى في طريقة ما بعد الوثني في Global.asax:

HttpCookie formsCookie = Request.Cookies[FormsAuthentication.FormsCookieName];

if (formsCookie != null)
{
    FormsAuthenticationTicket auth = FormsAuthentication.Decrypt(formsCookie.Value);

    Guid userID = new Guid(auth.UserData);

    var principal = new CustomPrincipal(Roles.Provider.Name, new GenericIdentity(auth.Name), userID);

    Context.User = Thread.CurrentPrincipal = principal;
}

لاحظ أنه في هذه الحالة ، مستمدة من CustomPrincipal من RolePrincipal (على الرغم من أنك إذا كنت لا تستخدم الأدوار ، أعتقد أنك تحتاج إلى استخلاص من GenericPrincipal) ، وتضيف ببساطة خاصية UserD ومواد التحميل الزائد للمُنشئ.

الآن ، أينما كنت بحاجة إلى معرف المستخدم في تطبيقك ، يمكنك القيام بذلك:

if(HttpContext.Current.Request.IsAuthenticated)
    Guid userID = ((CustomPrincipal)HttpContext.Current.User).UserID;

نصائح أخرى

لماذا لا تقوم أولاً بإجراء جميع مكالمات التفويض عبر واجهة. وبهذه الطريقة ، لا تحتاج إلى القلق من جميع التعليمات البرمجية التي تستخدم المصادقة بشأن كيفية تنفيذ تسجيل الدخول ، أو كيف يتم تخزين المسافة البادئة ، وما إلى ذلك.

public interface IAuthorization
{
    bool ValidateUser(LoginUser u, string password);
    LoginUser GetCurrentUser();
    void LogIn(LoginUser user);
    void LogOut();
    IIdentity GetCurrentUserIdentity();
}

يمكن أن يكون التخلص من iidentity getCurrentUserIdentity بأي طريقة تريدها ، ولكن يُنظر إليها عادةً على أنها دعوة إلى "httpcontext.current.user.identity"

public class Authorization : IAuthorization
{
    /// <summary>
    /// Get the IIdentity for the current logged in user
    /// </summary>
    /// <returns>IIdentity</returns>
    public virtual IIdentity GetCurrentUserIdentity()
    {
        return HttpContext.Current.User.Identity;
    }

    /// <summary>
    /// Log the user in
    /// </summary>
    /// <param name="user">User details</param>
    public void LogIn(LoginUser user)
    {
        InvalidCredentialsOnNullUser(user);
        FormsAuthentication.SetAuthCookie(user.Name, false);
    }

    /// <summary>
    /// Log the user out
    /// </summary>
    public void LogOut()
    {
        FormsAuthentication.SignOut();
    }

    private static void InvalidCredentialsOnNullUser(LoginUser user)
    {
        if (user == null)
        {
            throw new InvalidCredentialException("That user doesn't exist or is not valid.");
        }
    }

    // other methods....

}

فئة تسجيل الدخول التي تراها هي المعلومات التي يتم استردادها حول مستخدم العضوية. يتم ذلك بشكل شائع عبر العضوية Provider ولكن بالطبع يمكن القيام به طرقًا أخرى.

public class LoginUser
{
    public string Name;
    public Guid Key;
    public string EmailAddress;
    public bool IsApproved;
    public bool IsLockedOut;
    public DateTime CreationDate;
    public DateTime? LastLoginDate;
    public DateTime? LastPasswordChangedDate;
}

لست متأكدًا من أنني أفهم السؤال بشكل صحيح ولكن إذا كنت تشير إلى طريقة لاسترداد من هو المستخدم الحالي دون تمريره عبر عنوان URL (على سبيل المثال http: // localhost/controller/action؟ username = rame0) ثم يمكنك الاطلاع على استخدام thread.currentPrincipal.Identity.name أو httpcontext.current.user

هناك اختلافات دقيقة بين الاثنين. بحث هنا لمزيد من التفاصيل.

استخدام FormsAuthentication يمكنك تخزين اسم المستخدم في User.Identity.Name منشأه. إليك مثال بسيط على ما تبحث عنه. (باستخدام نفس الشيء SetAuth أنت تستخدم بالفعل)

public ViewResult Index() {
    return View(repository.GetUserProjects(this.User.Identity.Name));
}

هذا لا يتطلب منك تمرير اسم المستخدم من خلال معلمة QueryString.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top