Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Gilt für:
Externe Mandanten (weitere Informationen)
In diesem Lernprogramm erfahren Sie, wie Sie Benutzer mithilfe der systemeigenen Authentifizierung bei einer Einzelseiten-App (React Single Page App, SPA) anmelden.
In diesem Tutorial werden Sie:
- Aktualisieren Sie die React-App, um Benutzer mit Benutzername(E-Mail) und Kennwort anzumelden.
- Testen des Anmeldeablaufs.
Voraussetzungen
- Führen Sie die Schritte im Tutorial: Einrichten des CORS-Proxyservers zum Verwalten von CORS-Headern für die native Authentifizierung aus.
Definieren von Aufrufen, die die App an die systemeigene Authentifizierungs-API sendet
Während des Anmeldeflusses führt die App mehrere Aufrufe an die systemeigene Authentifizierungs-API aus, z. B. das Starten einer Anmeldeanforderung, das Auswählen einer Authentifizierungsmethode und das Anfordern von Sicherheitstoken.
Um diese Aufrufe zu definieren, öffnen Sie die datei scr/client/RequestTypes.ts, und fügen Sie dann den folgenden Codeausschnitt an:
export interface TokenRequestType {
continuation_token: string;
client_id: string;
grant_type: string;
scope: string;
password?: string;
oob?: string;
challenge_type?: string;
}
// Sign in
export interface TokenSignInType {
continuation_token: string;
grant_type: string;
password?: string;
oob?: string;
}
export interface ChallengeRequest {
client_id: string;
challenge_type: string;
continuation_token: string;
}
export interface SignInStartRequest {
client_id: string;
challenge_type: string;
username: string;
}
export interface SignInTokenRequest {
client_id: string;
grant_type: string;
continuation_token: string;
scope: string;
challenge_type?: string;
password?: string;
oob?: string;
}
Definieren Sie die Art der Antworten, die die App von der nativen Authentifizierungs-API erhält.
Um den Typ der Antworten zu definieren, die die App von der systemeigenen Authentifizierungs-API für den Anmeldevorgang erhalten kann, öffnen Sie die datei src/client/ResponseTypes.ts, und fügen Sie dann den folgenden Codeausschnitt an:
export interface TokenResponseType {
token_type: string;
scope: string;
expires_in: number;
access_token: string;
refresh_token: string;
id_token: string;
}
Verarbeiten von Anmeldeanforderungen
In diesem Abschnitt fügen Sie Code hinzu, der Anmeldeflussanforderungen verarbeitet. Beispiele für diese Anforderungen sind der Start eines Anmeldeflusses, das Auswählen einer Authentifizierungsmethode oder das Anfordern eines Sicherheitstokens.
Erstellen Sie dazu eine Datei namens src/client/SignInService.ts, und fügen Sie dann den folgenden Codeausschnitt hinzu:
import { CLIENT_ID, ENV } from "../config";
import { postRequest } from "./RequestClient";
import { ChallengeRequest, SignInStartRequest, TokenRequestType, TokenSignInType } from "./RequestTypes";
import { TokenResponseType } from "./ResponseTypes";
export const signInStart = async ({ username }: { username: string }) => {
const payloadExt: SignInStartRequest = {
username,
client_id: CLIENT_ID,
challenge_type: "password oob redirect",
};
return await postRequest(ENV.urlOauthInit, payloadExt);
};
export const signInChallenge = async ({ continuation_token }: { continuation_token: string }) => {
const payloadExt: ChallengeRequest = {
continuation_token,
client_id: CLIENT_ID,
challenge_type: "password oob redirect",
};
return await postRequest(ENV.urlOauthChallenge, payloadExt);
};
export const signInTokenRequest = async (request: TokenSignInType): Promise<TokenResponseType> => {
const payloadExt: TokenRequestType = {
...request,
client_id: CLIENT_ID,
challenge_type: "password oob redirect",
scope: "openid offline_access",
};
if (request.grant_type === "password") {
payloadExt.password = request.password;
}
if (request.grant_type === "oob") {
payloadExt.oob = request.oob;
}
return await postRequest(ENV.urlOauthToken, payloadExt);
};
Die challenge_type-Eigenschaft zeigt die Authentifizierungsmethoden an, die von der Client-App unterstützt werden. Diese App meldet sich per E-Mail mit Kennwort an, sodass der Abfragetypwert die Umleitung des Kennworts ist. Weitere Informationen finden Sie unter Aufforderungstypen.
Erstellen von UI-Komponenten
Während des Anmeldeflusses sammelt diese App die Anmeldeinformationen, den Benutzernamen (E-Mail) und das Kennwort des Benutzers, um sich beim Benutzer anzumelden. Nachdem sich der Benutzer erfolgreich angemeldet hat, zeigt die App die Details des Benutzers an.
Erstellen Sie einen Ordner namens /pages/signin im src Ordner.
Um das Anmeldeformular zu erstellen, anzuzeigen und zu übermitteln, erstellen Sie eine Datei src/pages/signin/SignIn.tsx, und fügen Sie dann den folgenden Code hinzu:
import React, { useState } from "react"; import { Link as LinkTo, useNavigate } from "react-router-dom"; import { signInStart, signInChallenge, signInTokenRequest } from "../../client/SignInService"; import { ErrorResponseType } from "../../client/ResponseTypes"; export const SignIn: React.FC = () => { const [email, setEmail] = useState<string>(""); const [password, setPassword] = useState<string>(""); const [error, setError] = useState<string>(""); const [isLoading, setIsloading] = useState<boolean>(false); const navigate = useNavigate(); const validateEmail = (email: string): boolean => { const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return re.test(String(email).toLowerCase()); }; const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); if (!validateEmail(email)) { setError("Invalid email format"); return; } setError(""); setIsloading(true); try { const res1 = await signInStart({ username: email, }); const res2 = await signInChallenge({ continuation_token: res1.continuation_token }); const res3 = await signInTokenRequest({ continuation_token: res2.continuation_token, grant_type: "password", password: password, }); navigate("/user", { state: res3 }); } catch (err) { setError("An error has occured " + (err as ErrorResponseType).error_description); } finally { setIsloading(false); } }; return ( <div className="login-form"> <form onSubmit={handleSubmit}> <h2>Login</h2> <div className="form-group"> <label>Email:</label> <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required /> </div> <div className="form-group"> <label>Password:</label> <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} required /> </div> {error && <div className="error">{error}</div>} {isLoading && <div className="warning">Sending request...</div>} <button type="submit" disabled={isLoading}>Login</button> </form> </div> ); };So zeigen Sie die Details des Benutzers nach einer erfolgreichen Anmeldung an:
Erstellen Sie eine Datei namens Client/Utils.ts, und fügen Sie dann den folgenden Codeausschnitt hinzu:
export function parseJwt(token: string) { var base64Url = token.split(".")[1]; var base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/"); var jsonPayload = decodeURIComponent( window .atob(base64) .split("") .map(function (c) { return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2); }) .join("") ); return JSON.parse(jsonPayload); }Erstellen Sie einen Ordner namens Benutzer im Ordner src/pages.
Erstellen Sie eine Datei namens src/pages/user/UserInfo.tsx, und fügen Sie dann den folgenden Codeausschnitt hinzu:
// User.tsx import React from "react"; import { useLocation } from "react-router-dom"; import { parseJwt } from "../../client/Utils"; export const UserInfo: React.FC = () => { const { state } = useLocation(); const decodedToken = parseJwt(state.access_token); const { given_name, scp, family_name, unique_name: email } = decodedToken; console.log(decodedToken); const familyName = family_name; const givenName = given_name; const tokenExpireTime = state.expires_in; const scopes = state.scope; return ( <div className="user-info"> <h2>User Information</h2> <div className="info-group"> <label>Given Name:</label> <span>{givenName}</span> </div> <div className="info-group"> <label>Family Name:</label> <span>{familyName}</span> </div> <div className="info-group"> <label>Email:</label> <span>{email}</span> </div> <div className="info-group"> <label>Token Expire Time:</label> <span>{tokenExpireTime}</span> </div> <div className="info-group"> <label>Scopes:</label> <span>{scopes}</span> </div> <div className="info-group"> <label>Token payload:</label> <span><pre>{JSON.stringify(decodedToken, null, 2)}</pre></span> </div> </div> ); };
Hinzufügen von App-Routen
Öffnen Sie die Datei src/AppRoutes.tsx, und ersetzen Sie den Inhalt durch den folgenden Code:
import { Route, Routes } from "react-router-dom";
import { SignIn } from "./pages/SignIn/SignIn";
import { UserInfo } from "./pages/User/UserInfo";
import { SignUp } from "./pages/SignUp/SignUp";
import { SignUpChallenge } from "./pages/SignUp/SignUpChallenge";
import { SignUpCompleted } from "./pages/SignUp/SignUpCompleted";
//For password reset
//import { ResetPassword } from "./pages/ResetAccount/ResetPassword";
export const AppRoutes = () => {
return (
<Routes>
<Route path="/" element={<SignUp />} />
<Route path="/signin" element={<SignIn />} />
<Route path="/user" element={<UserInfo />} />
<Route path="/signup" element={<SignUp />} />
<Route path="/signup/challenge" element={<SignUpChallenge />} />
<Route path="/signup/completed" element={<SignUpCompleted />} />
//For password reset
//<Route path="/reset" element={<ResetPassword />} />
</Routes>
);
};
Ausführen und Testen der App
Verwenden Sie die Schritte in Ausführen und Testen Ihrer App, um Ihre App auszuführen. Testen Sie diesmal jedoch den Anmeldeablauf, indem Sie das Benutzerkonto verwenden, mit dem Sie sich zuvor angemeldet haben.
Aktivieren der Anmeldung mit einem Alias oder Benutzernamen
Sie können Benutzern, die sich mit einer E-Mail-Adresse und einem Kennwort anmelden, auch die Möglichkeit geben, sich mit einem Benutzernamen und Kennwort anzumelden. Der Benutzername wird auch als alternativer Anmeldebezeichner bezeichnet, kann eine Kunden-ID, Kontonummer oder ein anderer Bezeichner sein, den Sie als Benutzernamen verwenden möchten.
Sie können dem Benutzerkonto Benutzernamen manuell über das Microsoft Entra Admin Center zuweisen oder in Ihrer App über die Microsoft Graph-API automatisieren.
Führen Sie die Schritte im Artikel 'Anmelden mit einem Alias oder Benutzernamen' aus, um Ihren Benutzern die Anmeldung mit einem Benutzernamen in Ihrer Anwendung zu ermöglichen:
- Aktivieren Sie die Anmeldung mit dem Benutzernamen.
- Erstellen Sie Benutzer mit Benutzername im Admin Center , oder aktualisieren Sie vorhandene Benutzer, indem Sie einen Benutzernamen hinzufügen. Alternativ können Sie auch die Benutzererstellung und -aktualisierung in Ihrer App mithilfe der Microsoft Graph-API automatisieren.