Aplicación de página única: Inicio y cierre de sesión
Artículo
Aprenda a agregar el inicio de sesión al código de la aplicación de página única.
Antes de obtener tokens para acceder a las API de la aplicación, necesita un contexto de usuario autenticado. Puede iniciar la sesión de los usuarios en la aplicación con MSAL.js de dos maneras:
Opcionalmente, también puede pasar los ámbitos de las API para las que necesita que el usuario dé su consentimiento en el momento de iniciar sesión.
Si su aplicación ya tiene acceso a un contexto de usuario autenticado o un token de identificación, puede omitir el paso de inicio de sesión y adquirir los tokens directamente. Para detalles, consulte SSO con sugerencia de usuario.
Elección entre una experiencia de inicio de sesión emergente o redireccionamiento
La elección de una u otra experiencia depende del flujo de la aplicación:
Si no quiere que los usuarios salgan de la página principal de la aplicación durante la autenticación, se recomienda el método de ventana emergente. Dado que la redirección de la autenticación tiene lugar en una ventana emergente, se conserva el estado de la aplicación principal.
Si los usuarios tienen restricciones del explorador o directivas donde las ventanas emergentes están deshabilitadas, puede usar el método de redirección. Use el método de redirección con Internet Explorer, ya que hay problemas conocidos con las ventanas emergentes en este explorador.
El contenedor MSAL Angular le permite proteger rutas específicas de la aplicación con solo agregar el valor MsalGuard a la definición de ruta. Esta protección invocará al método para iniciar sesión cuando se tenga acceso a esa ruta.
// In app-routing.module.ts
import { NgModule } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";
import { ProfileComponent } from "./profile/profile.component";
import { MsalGuard } from "@azure/msal-angular";
import { HomeComponent } from "./home/home.component";
const routes: Routes = [
{
path: "profile",
component: ProfileComponent,
canActivate: [MsalGuard],
},
{
path: "",
component: HomeComponent,
},
];
@NgModule({
imports: [RouterModule.forRoot(routes, { useHash: false })],
exports: [RouterModule],
})
export class AppRoutingModule {}
Para obtener una experiencia de ventana emergente, establezca la configuración de interactionType en InteractionType.Popup en la configuración de Guard. También puede pasar los ámbitos que requieren el consentimiento tal como se detalla a continuación:
El contenedor MSAL Angular le permite proteger rutas específicas de la aplicación con solo agregar el valor MsalGuard a la definición de ruta. Esta protección invocará al método para iniciar sesión cuando se tenga acceso a esa ruta.
// In app-routing.module.ts
import { NgModule } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";
import { ProfileComponent } from "./profile/profile.component";
import { MsalGuard } from "@azure/msal-angular";
import { HomeComponent } from "./home/home.component";
const routes: Routes = [
{
path: "profile",
component: ProfileComponent,
canActivate: [MsalGuard],
},
{
path: "",
component: HomeComponent,
},
];
@NgModule({
imports: [RouterModule.forRoot(routes, { useHash: false })],
exports: [RouterModule],
})
export class AppRoutingModule {}
Para usar la experiencia de ventana emergente, habilite la opción de configuración popUp. También puede pasar los ámbitos que requieren el consentimiento tal como se detalla a continuación:
El contenedor React de MSAL permite proteger componentes específicos al encapsularlos en el componente MsalAuthenticationTemplate. Este componente invocará el inicio de sesión si un usuario aún no ha iniciado sesión o representará los componentes secundarios en caso contrario.
import { InteractionType } from "@azure/msal-browser";
import { MsalAuthenticationTemplate, useMsal } from "@azure/msal-react";
function WelcomeUser() {
const { accounts } = useMsal();
const username = accounts[0].username;
return <p>Welcome, {username}</p>;
}
// Remember that MsalProvider must be rendered somewhere higher up in the component tree
function App() {
return (
<MsalAuthenticationTemplate interactionType={InteractionType.Popup}>
<p>This will only render if a user is signed-in.</p>
<WelcomeUser />
</MsalAuthenticationTemplate>
);
}
También puede usar las API de @azure/msal-browser directamente para invocar un inicio de sesión emparejado con los componentes AuthenticatedTemplate y/o UnauthenticatedTemplate para representar contenido específico para los usuarios que han iniciado sesión o que la han cerrado, respectivamente. Este es el enfoque recomendado si necesita invocar el inicio de sesión como resultado de la interacción del usuario, como un clic de botón.
import {
useMsal,
AuthenticatedTemplate,
UnauthenticatedTemplate,
} from "@azure/msal-react";
function signInClickHandler(instance) {
instance.loginPopup();
}
// SignInButton Component returns a button that invokes a popup login when clicked
function SignInButton() {
// useMsal hook will return the PublicClientApplication instance you provided to MsalProvider
const { instance } = useMsal();
return <button onClick={() => signInClickHandler(instance)}>Sign In</button>;
}
function WelcomeUser() {
const { accounts } = useMsal();
const username = accounts[0].username;
return <p>Welcome, {username}</p>;
}
// Remember that MsalProvider must be rendered somewhere higher up in the component tree
function App() {
return (
<>
<AuthenticatedTemplate>
<p>This will only render if a user is signed-in.</p>
<WelcomeUser />
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<p>This will only render if a user is not signed-in.</p>
<SignInButton />
</UnauthenticatedTemplate>
</>
);
}
const config = {
auth: {
clientId: "your_app_id",
redirectUri: "your_app_redirect_uri", //defaults to application start page
postLogoutRedirectUri: "your_app_logout_redirect_uri",
},
};
const loginRequest = {
scopes: ["User.ReadWrite"],
};
let accountId = "";
const myMsal = new PublicClientApplication(config);
function handleResponse(response) {
if (response !== null) {
accountId = response.account.homeAccountId;
// Display signed-in user content, call API, etc.
} else {
// In case multiple accounts exist, you can select
const currentAccounts = myMsal.getAllAccounts();
if (currentAccounts.length === 0) {
// no accounts signed-in, attempt to sign a user in
myMsal.loginRedirect(loginRequest);
} else if (currentAccounts.length > 1) {
// Add choose account code here
} else if (currentAccounts.length === 1) {
accountId = currentAccounts[0].homeAccountId;
}
}
}
myMsal.handleRedirectPromise().then(handleResponse);
Los métodos de redirección no devuelven una promesa, dado que se abandona la aplicación principal. Para procesar los tokens devueltos y acceder a ellos, registre las devoluciones de llamada correctas y con error antes de llamar a los métodos de redirección.
El código aquí es el mismo que se describió anteriormente en la sección sobre el inicio de sesión con una ventana emergente, salvo que interactionType está establecido en InteractionType.Redirect para la configuración de MsalGuard y se arranca MsalRedirectComponent para controlar los redireccionamientos.
El código aquí es el mismo que el que se describió anteriormente en la sección sobre el inicio de sesión con una ventana emergente. El flujo predeterminado es de redirección.
El contenedor React de MSAL permite proteger componentes específicos al encapsularlos en el componente MsalAuthenticationTemplate. Este componente invocará el inicio de sesión si un usuario aún no ha iniciado sesión o representará los componentes secundarios en caso contrario.
import { InteractionType } from "@azure/msal-browser";
import { MsalAuthenticationTemplate, useMsal } from "@azure/msal-react";
function WelcomeUser() {
const { accounts } = useMsal();
const username = accounts[0].username;
return <p>Welcome, {username}</p>;
}
// Remember that MsalProvider must be rendered somewhere higher up in the component tree
function App() {
return (
<MsalAuthenticationTemplate interactionType={InteractionType.Redirect}>
<p>This will only render if a user is signed-in.</p>
<WelcomeUser />
</MsalAuthenticationTemplate>
);
}
También puede usar las API de @azure/msal-browser directamente para invocar un inicio de sesión emparejado con los componentes AuthenticatedTemplate y/o UnauthenticatedTemplate para representar contenido específico para los usuarios que han iniciado sesión o que la han cerrado, respectivamente. Este es el enfoque recomendado si necesita invocar el inicio de sesión como resultado de la interacción del usuario, como un clic de botón.
import {
useMsal,
AuthenticatedTemplate,
UnauthenticatedTemplate,
} from "@azure/msal-react";
function signInClickHandler(instance) {
instance.loginRedirect();
}
// SignInButton Component returns a button that invokes a popup login when clicked
function SignInButton() {
// useMsal hook will return the PublicClientApplication instance you provided to MsalProvider
const { instance } = useMsal();
return <button onClick={() => signInClickHandler(instance)}>Sign In</button>;
}
function WelcomeUser() {
const { accounts } = useMsal();
const username = accounts[0].username;
return <p>Welcome, {username}</p>;
}
// Remember that MsalProvider must be rendered somewhere higher up in the component tree
function App() {
return (
<>
<AuthenticatedTemplate>
<p>This will only render if a user is signed-in.</p>
<WelcomeUser />
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<p>This will only render if a user is not signed-in.</p>
<SignInButton />
</UnauthenticatedTemplate>
</>
);
}
Comportamiento de cierre de sesión en exploradores
Cuantos más aplicaciones haya iniciado sesión un usuario y quiera cerrar sesión, más posibilidades de problemas se produzcan dadas las formas limitadas de implementar dicha funcionalidad en los exploradores. Los procedimientos recomendados de privacidad de Internet de Microsoft recomiendan que en un dispositivo compartido en el que un usuario quiera cerrar la sesión de una aplicación, el usuario debe usar el modo privado o de incógnito de un explorador y cerrar todas las ventanas del explorador antes de salir del dispositivo.
En los dispositivos que no se comparten, los usuarios deben aprovechar una pantalla de bloqueo del sistema operativo para que puedan bloquear o cerrar la sesión de su sistema operativo completo en el dispositivo. Microsoft usa su página de cierre de sesión para recordar a los usuarios estos procedimientos recomendados para ayudar a mejorar su privacidad y seguridad.
Para los usuarios que no eligen seguir el enfoque seguro, la aplicación puede intentar prepararse para ambos casos:
El usuario ha iniciado el cierre de sesión desde la aplicación directamente.
Desde otra aplicación que comparte el estado de inicio de sesión con la nueva aplicación, pero administra sus propios tokens o cookies de sesión.
En el primer caso, en las secciones siguientes se describen las opciones sobre cómo cerrar la sesión del usuario desde una aplicación local mediante un elemento emergente o redireccionamiento.
En el segundo caso en el que se inicia el cierre de sesión desde otra aplicación, Microsoft usa el cierre de sesión del canal front-end de OpenID Connect para el cierre de sesión federado. Hay algunas limitaciones en esta implementación en las que el contenido de terceros está bloqueado, como cuando los exploradores bloquean cookies de terceros de forma predeterminada.
Los siguientes métodos emergentes y redireccionamiento finalizarán la sesión del usuario en el punto de conexión y para la aplicación local, pero es posible que no borre inmediatamente la sesión de otras aplicaciones federadas, si se bloquea la comunicación del canal front-channel. Para un cierre de sesión federado garantizado independientemente del comportamiento del explorador, se recomiendan los procedimientos recomendados para los usuarios de usar la exploración privada o las pantallas de bloqueo.
Cierre de sesión con una ventana emergente
Este modo es compatible, pero tiene las mismas limitaciones de inicio de sesión con una ventana emergente que las restricciones o directivas de exploradores pueden deshabilitar las ventanas emergentes. MSAL.js v2 y versiones posteriores proporciona un método logoutPopup que limpia la caché en el almacenamiento del explorador y abre una ventana emergente a la página de cierre de sesión de Microsoft Entra. Después de cerrar la sesión, Microsoft Entra ID redirige la ventana emergente de nuevo a su aplicación y MSAL.js cerrará la ventana emergente.
Puede configurar el URI al que Microsoft Entra ID debe redirigir después de cerrar la sesión configurando postLogoutRedirectUri. Este URI se debe registrar como un URI de redirección en el registro de la aplicación.
También puede configurar logoutPopup para redirigir la ventana principal a otra página, como la página principal o la página de inicio de sesión, una vez completado el cierre de sesión mediante el paso de mainWindowRedirectUri como parte de la solicitud.
El cierre de sesión con una ventana emergente no se admite en MSAL Angular v1
import {
useMsal,
AuthenticatedTemplate,
UnauthenticatedTemplate,
} from "@azure/msal-react";
function signOutClickHandler(instance) {
const logoutRequest = {
account: instance.getAccountByHomeId(homeAccountId),
mainWindowRedirectUri: "your_app_main_window_redirect_uri",
postLogoutRedirectUri: "your_app_logout_redirect_uri",
};
instance.logoutPopup(logoutRequest);
}
// SignOutButton Component returns a button that invokes a popup logout when clicked
function SignOutButton() {
// useMsal hook will return the PublicClientApplication instance you provided to MsalProvider
const { instance } = useMsal();
return (
<button onClick={() => signOutClickHandler(instance)}>Sign Out</button>
);
}
// Remember that MsalProvider must be rendered somewhere higher up in the component tree
function App() {
return (
<>
<AuthenticatedTemplate>
<p>This will only render if a user is signed-in.</p>
<SignOutButton />
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<p>This will only render if a user is not signed-in.</p>
</UnauthenticatedTemplate>
</>
);
}
Cierre de sesión con un redireccionamiento
MSAL.js proporciona un método logout en v1 e introdujo un método logoutRedirect en v2 que borra la memoria caché en el almacenamiento del explorador y redirige la ventana a la página de cierre de sesión de Microsoft Entra. Después de cerrar la sesión, Microsoft Entra ID redirige de forma predeterminada a la página que ha invocado el cierre de sesión.
Dado que el usuario no verá el recordatorio de Microsoft de procedimientos recomendados de privacidad de Internet sobre el uso de un explorador privado y una pantalla de bloqueo, es posible que la aplicación spa también quiera describir los procedimientos recomendados y recordar a los usuarios que cierren todas las ventanas del explorador.
Puede configurar el URI de redirección tras el cierre de sesión mediante el establecimiento del valor postLogoutRedirectUri. Este URI se debe registrar como un URI de redirección en el registro de la aplicación.
import {
useMsal,
AuthenticatedTemplate,
UnauthenticatedTemplate,
} from "@azure/msal-react";
function signOutClickHandler(instance) {
const logoutRequest = {
account: instance.getAccountByHomeId(homeAccountId),
postLogoutRedirectUri: "your_app_logout_redirect_uri",
};
instance.logoutRedirect(logoutRequest);
}
// SignOutButton Component returns a button that invokes a redirect logout when clicked
function SignOutButton() {
// useMsal hook will return the PublicClientApplication instance you provided to MsalProvider
const { instance } = useMsal();
return (
<button onClick={() => signOutClickHandler(instance)}>Sign Out</button>
);
}
// Remember that MsalProvider must be rendered somewhere higher up in the component tree
function App() {
return (
<>
<AuthenticatedTemplate>
<p>This will only render if a user is signed-in.</p>
<SignOutButton />
</AuthenticatedTemplate>
<UnauthenticatedTemplate>
<p>This will only render if a user is not signed-in.</p>
</UnauthenticatedTemplate>
</>
);
}