2010-01-06 2 views
1

비슷한 질문이 제기되었지만 ASP.NET MVC (및 컨트롤러 측면)를 구체적으로 처리하는 복제본을 찾을 수 없습니다. MVC 모델에서 사용자가 로그인했는지 여부에 대한 정보를 설정하거나 얻는 모범 사례

, 내 이해 컨트롤러가있는 경우, 로그온 한 사용자를 확인하는 HttpContext를 사용을 처리해야한다는 것입니다 다음과 같이

내 질문입니다. 컨트롤러가이 정보를보기에 표시 할 수 있으므로보기 자체에서 이러한 조회를 수행 할 필요가 없습니다.

어떻게하는지에 대한 표준이 있습니까? 다음과 같이

내 현재 설정은 [단순화] 내 모든 다른 컨트롤러를 상속합니다 BaseController을 가지고

. 나는을 ViewData 값을 확인할 수 있습니다 내보기에, 자연스럽게, 그리고

protected override void Initialize(System.Web.Routing.RequestContext requestContext) 
{ 
    base.Initialize(requestContext); 
    ViewData["IsUserLoggedIn"] = IsUserLoggedIn; // bool property checking HttpContext.User.Identity.IsAuthenticated; 
    ViewData["CurrentUser"] = CurrentUser; // Property returning logged in user, or null. 

} 

: BaseController에서

, 나는 다음과 같은 대체를 수행합니다.

어떻게하면 이 가능합니까? 내 설정에 문제가 있는지 알고 싶습니다. 무엇이 잘못 되었나요? 나는 내 솔루션에 100 % 만족하지 못합니다. 주로 사이클에 익숙하지 않아서 올바른 코드에 코드를 배치했는지 확실하지 않기 때문입니다.

나는 "하나의 대답으로 모두 묶습니다"라는 인식이 없으므로 나는 대부분의 통찰력을 제공하는 대답을 받아들입니다.

답변

2

나는 일반적으로 암호화 된 요소를 쿠키에 넣습니다. 그 요소는 뭐든지 될 수 있지만, 일반적으로 사용자 이름이됩니다.

그런 다음 Global.asax.cs에서 Application_AuthenticateRequest를 구현합니다. 페이지가로드 될 때마다이 메소드가 시스템에 의해 호출됩니다. 쿠키를 검사하는 방법에서 쿠키가 있으면 사용자를로드하려고 시도합니다. 사용자가 성공적으로로드되면 로그인 한 사용자가 있다는 것을 알게되고 현재 스레드의 현재 Principal 속성을 해당 사용자로 설정합니다.

CurrentPrincipal이 현재 스레드에 설정되면 컨트롤러의 뷰, 비즈니스 계층, 실행 경로의 모든 위치에서 해당 사용자에 액세스 할 수 있습니다.

쿠키를 사용할 수없는 경우 ViewData에서 쿠키를 전달하고 (경우에 따라 다시 암호화 됨) 숨겨진 변수에 저장합니다. 그런 다음 Controller :: OnActionExecuting을 실행하면 AuthenticateRequest에서 일반적으로 수행 한 것과 동일한 작업을 수행합니다 (즉, 사용자를로드하여 스레드에 배치).

+0

흥미로운 접근법. 쿠키 스키마는 FormsAuthentication 쿠키와 어떤 관련이 있습니까 (물론 Forms 인증을 사용하는 경우). – Terje

+0

FormsAuthentication을 사용하지 않지만 일반 FormsAuthenticationTicket 및 HttpCookie를 사용합니다. 사용자가 로그인을 시도하면 내 컨트롤러는 먼저 내 도메인 계층을 호출하여 사용자 로그인을 시도합니다. 성공하면 내 컨트롤러는 암호화 된 사용자 이름을 포함하는 FormsAuthenticationTicket 개체를 만들고이를 HttpCookie에 저장하고 해당 쿠키를 Response.Cookies 컬렉션에 저장합니다. 그동안 사용자가 실제로 로그인했는지 추적하기 위해 시스템에 무언가를 추가해야했습니다 (예 : 티켓에서 사용자를로드 한 다음 로그인 한 사용자인지 확인). –

+0

나는 통찰력을 찾고 있었고, 나는 어떤 것을 얻었다. 감사. 이 접근법을 살펴보고 현재 사용하고있는 것과 비교 한 내 자신의 경험을 살펴볼 것입니다. 사용자가 로그인했는지 여부를 추적합니다. 나는 BaseController의 Initialize가 호출 될 때마다 그것을 업데이트하면서 내 user 테이블의 마지막 활동 도장으로 처리한다. – Terje

0

모든 컨트롤러가 상속하는 BaseController 클래스가 있습니다. 그것은 세션에 저장되어있는 "CurrentUser"속성을 가지고 있습니다. 내 컨트롤러의 전체 코드는 사용자를 검색하기위한 좀 더 많은 로직을 가지고 있지만 이것이 기본적인 아이디어입니다.

public class BaseController : Controller 
{ 

User _currentUser = null; 
public User CurrentUser 
{ 
    get 
    { 
     if (_currentUser == null) 
      _currentUser = (User)HttpContext.Session["CurrentUser"]; 

     return _currentUser; 

    } 
    set 
    { 
     _currentUser = value; 
     HttpContext.Session["CurrentUser"] = value; 
     } 
    } 
} 


} 

내 모델은 모두 CurrentUser 속성이있는 BaseModel 클래스를 상속합니다.

public class BaseModel 
{ 
    public User CurrentUser { get; set; } 
} 

public class HomeIndexData : BaseModel 
{ 

} 

그러면 내 컨트롤러가 사용자에게 강력한 형식의보기를 허용하는 모델을 전달합니다.

[HttpGet] 
public ActionResult Index() 
{ 
    HomeIndexData data = new HomeIndexData(); 
    data.CurrentUser = this.CurrentUser; 

    return View(data); 
} 

이 기술을 사용하면 BaseModel을 사용하여 강력한 형식의 마스터 페이지를 만들 수 있습니다.

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage<BaseModel>" %> 
+0

이전 프로젝트에서 비슷한 접근 방식을 사용했습니다. 대부분 잘 작동했지만, 어떤 경우 BaseModel을 확장하는 것이 의미가 없거나 불가능했습니다. (DataTable 클래스에 직접 매핑하거나 외부 프로젝트 .dll 파일에서 모델 개체를 사용하여 상상해보십시오.) 그래서 ViewData로 끝났습니다. 또한 CurrentUser 속성에 대해 Session을 사용합니다. 이것에 대한 좋은 이유가 있습니까? 예를 들어 Controller.HttpContext.User.Identity를 사용할 수없는 이유는 무엇입니까? 또는 더 나은 질문은 왜 그것이 더 나쁜 아이디어라고 생각합니까? – Terje

+0

User.Identity가 아닌 사용자 지정 사용자 개체를 사용하면 상황에 맞게 확장 할 수 있습니다. 예를 들어 마스터 페이지에는 사용자의 이름과 성을 표시하는 섹션이 있으며, 여기서는 User.Identity.Name만으로는 할 수 없습니다. 개인적으로 앱에 필요한 DataTable에 항목이있는 경우 POCO를 만들고 DataTable로 채 웁니다. –

관련 문제