2010-01-06 5 views
1

Je sais que des questions similaires ont été posées auparavant, mais je n'ai pas pu trouver de doublon qui gère spécifiquement ASP.NET MVC (et l'aspect du contrôleur).Meilleure pratique pour définir/obtenir des informations sur si l'utilisateur est connecté ou non

Ma question est la suivante:

Dans un modèle MVC, je crois comprendre que le contrôleur doit gérer l'utilisation de HttpContext pour déterminer qui est connecté, le cas échéant. C'est ainsi que le contrôleur peut présenter cette information à la vue, de sorte que la vue elle-même n'a pas à effectuer ces recherches.

Existe-t-il un standard de fait sur la façon de le faire?

Ma configuration actuelle est la suivante [simplifiée]

J'ai un BaseController, que tous mes autres contrôleurs héritent.

En BaseController, j'effectue la commande prioritaire suivante:

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. 

} 

Puis, naturellement, dans mes vues, je peux vérifier les valeurs vidéotex.

Comment faire vous le faire? J'aimerais savoir si quelque chose ne va pas dans ma configuration, et si oui, quel est le problème? Je ne suis pas à 100% à l'aise avec ma solution, principalement parce que je ne connais pas très bien le cycle, et je ne sais pas si j'ai placé mon code au bon endroit. Je suis conscient qu'il n'y a peut-être pas «une seule réponse qui les lie tous», j'accepte la réponse qui offre le plus de perspicacité.

Répondre

2

Je place généralement un élément chiffré dans un cookie. Cet élément peut être n'importe quoi, mais je le fais généralement le nom d'utilisateur.

Ensuite, dans Global.asax.cs, j'implémente Application_AuthenticateRequest. Chaque fois qu'une page est chargée, cette méthode est appelée par le système. Dans cette méthode, je vérifie le cookie, s'il existe, j'essaie de charger l'utilisateur. Si l'utilisateur se charge correctement, je sais que je dispose d'un utilisateur connecté et que j'ai défini la propriété Principal en cours Threads pour cet utilisateur. Une fois que CurrentPrincipal est défini sur le thread actuel, vous pouvez accéder à cet utilisateur depuis votre Controller, votre View, votre Business Layer, n'importe où dans votre chemin d'exécution.

Si je ne peux pas utiliser les cookies pour une raison quelconque, je les transmettrai dans ViewData (à nouveau chiffré au cas où) et les stockerais dans des variables cachées. Puis, lorsque Controller :: OnActionExecuting s'exécute, je fais le même travail que j'ai fait dans AuthenticateRequest (c'est-à-dire charge l'utilisateur et le place sur le thread).

+0

Approche intéressante. Comment votre schéma de cookies se rapporte-t-il au cookie FormsAuthentication (si vous utilisez l'authentification par formulaire, bien sûr)? – Terje

+0

Je n'utilise pas FormsAuthentication, mais j'utilise un FormsAuthenticationTicket et un HttpCookie réguliers. Lorsqu'un utilisateur tente de se connecter, mon contrôleur appelle d'abord ma couche de domaine pour essayer de se connecter à l'utilisateur. Si cela réussit, mon contrôleur crée un objet FormsAuthenticationTicket contenant mon nom d'utilisateur chiffré, le place dans un HttpCookie et place ce cookie dans la collection Response.Cookies. Dans le passé, j'ai également dû ajouter quelque chose au système pour suivre l'utilisateur qui était connecté (c'est-à-dire que vous chargez l'utilisateur à partir du ticket, puis vérifiez s'il était connecté). –

+0

Je cherchais un aperçu, et j'en ai eu. Merci. Je vais regarder dans cette approche et voir de ma propre expérience comment il se compare à ce que j'utilise actuellement. Suivre si les utilisateurs sont connectés ou non Je gère cela avec un tampon de dernière activité dans ma table utilisateur, en le mettant à jour à chaque fois que l'initialisation de BaseController est appelée. – Terje

0

J'ai une classe BaseController dont tous mes contrôleurs héritent. Il a une propriété "CurrentUser" qui est stockée dans la session. Le code complet pour mon contrôleur a un peu plus de logique pour récupérer l'utilisateur, mais c'est l'idée de base. Mes modèles héritent tous d'une classe BaseModel qui possède également une propriété CurrentUser. Ensuite, mes contrôleurs transmettent l'utilisateur au modèle, ce qui me permet d'avoir des vues fortement typées.

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

    return View(data); 
} 

Avec cette technique, je peux également avoir une page maître fortement typée en utilisant BaseModel.

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

J'ai utilisé une approche similaire sur un projet antérieur. Dans la plupart des cas, cela a bien fonctionné, mais dans certains cas, cela n'a pas semblé [ou il n'a pas été possible] d'étendre BaseModel. (Imaginer le mappage aux classes DataTable directement, ou en utilisant des objets de modèle de fichiers .dll de projet externe, par exemple). Donc, je me suis retrouvé avec ViewData. En outre, vous utilisez Session pour votre propriété CurrentUser. Y a-t-il une [bonne] raison à cela? Par exemple, pourquoi ne pas utiliser Controller.HttpContext.User.Identity? Ou peut-être une meilleure question est, pourquoi pensez-vous que c'est une pire idée? – Terje

+0

Avoir un objet utilisateur personnalisé plutôt que User.Identity le rend un peu plus extensible dans notre situation. Par exemple, notre page maître a une section qui affiche le nom et prénom de l'utilisateur, quelque chose que nous ne pouvons pas faire avec seulement User.Identity.Name. Personnellement, si j'ai des éléments dans un DataTable dont l'application a besoin, je préfère créer un objet POCO et le remplir avec le DataTable. –

Questions connexes