Je viens du monde Asp.Net MVC où les utilisateurs essayant d'accéder à une page qu'ils ne sont pas autorisés sont automatiquement redirigés vers la page de connexion.
J'essaye de reproduire ce comportement sur Angular. Je suis tombé sur le décorateur @CanActivate, mais il en résulte que le composant ne se rend pas du tout, pas de redirection.
Ma question est la suivante:
- Angular fournit-il un moyen d'atteindre ce comportement?
- Si c'est le cas, comment? Est-ce une bonne pratique?
- Sinon, quelle serait la meilleure pratique pour gérer l'autorisation des utilisateurs dans Angular?
Réponses:
Mise à jour: J'ai publié un projet squelette complet Angular 2 avec intégration OAuth2 sur Github qui montre la directive mentionnée ci-dessous en action.
Une façon d'y parvenir serait d'utiliser un fichier
directive
. Contrairement à Angular 2components
, qui sont essentiellement de nouvelles balises HTML (avec code associé) que vous insérez dans votre page, une directive attributive est un attribut que vous insérez dans une balise qui provoque un certain comportement. Documents ici .La présence de votre attribut personnalisé provoque des choses pour le composant (ou élément HTML) dans lequel vous avez placé la directive. Considérez cette directive que j'utilise pour mon application Angular2 / OAuth2 actuelle:
Cela utilise un service d'authentification que j'ai écrit pour déterminer si l'utilisateur est déjà connecté ou non et s'abonne également à l'événement d'authentification afin qu'il puisse expulser un utilisateur s'il se déconnecte ou expire.
Vous pourriez faire la même chose. Vous créeriez une directive comme la mienne qui vérifie la présence d'un cookie nécessaire ou d'autres informations d'état indiquant que l'utilisateur est authentifié. S'ils n'ont pas les indicateurs que vous recherchez, redirigez l'utilisateur vers votre page publique principale (comme je le fais) ou votre serveur OAuth2 (ou autre). Vous mettriez cet attribut de directive sur n'importe quel composant qui doit être protégé. Dans ce cas, il pourrait être appelé
protected
comme dans la directive que j'ai collée ci-dessus.Ensuite, vous voudrez naviguer / rediriger l'utilisateur vers une vue de connexion dans votre application et y gérer l'authentification. Vous devrez changer l'itinéraire actuel pour celui que vous vouliez faire. Donc, dans ce cas, vous utiliserez l'injection de dépendances pour obtenir un objet Router dans la
constructor()
fonction de votre directive, puis vous utiliseriez lanavigate()
méthode pour envoyer l'utilisateur à votre page de connexion (comme dans mon exemple ci-dessus).Cela suppose que vous ayez une série de routes quelque part contrôlant une
<router-outlet>
balise qui ressemble à ceci, peut-être:Si, à la place, vous deviez rediriger l'utilisateur vers une URL externe , telle que votre serveur OAuth2, votre directive ferait quelque chose comme ceci:
la source
Voici un exemple mis à jour utilisant Angular 4 (également compatible avec Angular 5-8)
Itinéraires avec route d'origine protégée par AuthGuard
AuthGuard redirige vers la page de connexion si l'utilisateur n'est pas connecté
Mise à jour pour transmettre l'URL d'origine des paramètres de requête à la page de connexion
Pour l'exemple complet et la démonstration de travail, vous pouvez consulter cet article
la source
currentUser
dans lelocalStorage
serait toujours en mesure d'accéder à la route protégée? par exemple.localStorage.setItem('currentUser', 'dddddd')
?Utilisation avec le routeur final
Avec l'introduction du nouveau routeur, il est devenu plus facile de garder les routes. Vous devez définir une garde, qui agit comme un service, et l'ajouter à l'itinéraire.
Passez maintenant le
LoggedInGuard
à la route et ajoutez-le également auproviders
tableau du module.La déclaration du module:
Article de blog détaillé sur son fonctionnement avec la version finale: https://medium.com/@blacksonic86/angular-2-authentication-revisited-611bf7373bf9
Utilisation avec le routeur obsolète
Une solution plus robuste consiste à étendre
RouterOutlet
et lors de l'activation d'une route, vérifiez si l'utilisateur est connecté. De cette façon, vous n'avez pas à copier et coller votre directive dans chaque composant. De plus, la redirection basée sur un sous-composant peut être trompeuse.Le
UserService
représente l'endroit où réside votre logique métier, que l'utilisateur soit connecté ou non. Vous pouvez l'ajouter facilement avec DI dans le constructeur.Lorsque l'utilisateur accède à une nouvelle URL sur votre site Web, la méthode d'activation est appelée avec l'instruction actuelle. À partir de là, vous pouvez saisir l'url et décider si elle est autorisée ou non. Sinon, redirigez-vous simplement vers la page de connexion.
Une dernière chose reste à faire pour que cela fonctionne, c'est de le passer à notre composant principal au lieu de celui intégré.
Cette solution ne peut pas être utilisée avec le
@CanActive
décorateur de cycle de vie, car si la fonction qui lui est transmise résout false, la méthode activate duRouterOutlet
ne sera pas appelée.A également écrit un article de blog détaillé à ce sujet: https://medium.com/@blacksonic86/authentication-in-angular-2-958052c64492
la source
Failed to lint <classname>.router-outlet.ts[15,28]. In the constructor of class "LoggedInRouterOutlet", the parameter "nameAttr" uses the @Attribute decorator, which is considered as a bad practice. Please, consider construction of type "@Input() nameAttr: string".
Impossible de comprendre quoi changer dans le constructeur ("_parentRounter") pour se débarrasser de ce message. Des pensées?_parentRouter: Router, @Input() nameAttr: string,
et tslint ne lève plus l'erreur. Également remplacé l'importation "Attribut" vers "Entrée" à partir du noyau angulaire. J'espère que cela t'aides.Veuillez ne pas remplacer la prise du routeur! C'est un cauchemar avec la dernière version du routeur (3.0 beta).
Utilisez plutôt les interfaces CanActivate et CanDeactivate et définissez la classe sur canActivate / canDeactivate dans votre définition d'itinéraire.
Comme ça:
Classe:
Voir aussi: https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard
la source
En suivant les réponses impressionnantes ci-dessus, je voudrais également
CanActivateChild
: garder les routes des enfants. Il peut être utilisé pour ajouterguard
aux enfants des routes utiles pour des cas tels que les ACLÇa va comme ça
Ceci est tiré de https://angular.io/docs/ts/latest/guide/router.html#!#can-activate-guard
la source
Reportez-vous à ce code, fichier auth.ts
la source
1. Create a guard as seen below. 2. Install ngx-cookie-service to get cookies returned by external SSO. 3. Create ssoPath in environment.ts (SSO Login redirection). 4. Get the state.url and use encodeURIComponent.
la source