We have a configuration like this in our login section, this.checkRecaptcha() .pipe( switchMap(isValid => isValid ? this.authService .login(loginParams) .pipe(this.handleLoginError(loginParams)) .pipe( tap(() => { if (this.linkUser) { this.switchToLinkUser(); } }), ) : of(null), ), finalize(() => (this.inProgress = false)), ) .subscribe();
The handle error part is like this:
private handleLoginError(loginParams?: LoginParams) { return catchError(err => { const errorDescription = err.error?.error_description; debugger; switch (errorDescription) { case REQUIRES_TWO_FACTOR: { const data = {
...loginParams,
userId: err.error.userId,
};
this.securityCodeService.data = { ...data, twoFactorToken: err.error.twoFactorToken };
this.recoveryCodeService.data.set({ ...data });
return from(this.router.navigate(['/account/send-security-code']));
}
case PERIODICALLY_CHANGE_PASSWORD:
case RE_LOGIN_CONFIRMATION_TOKEN:
debugger;
case "You are not allowed to login! Your account is inactive or needs to confirm your email/phone number.":
const currentUserId = this.configStateService.getDeep('currentUser.id');//userid is not coming
It falls into this section, but the userid isn't returned. In this or a similar case, we need to retrieve the userid. We tried to get the userid from here because in the demo abp, the userid is expected in a dto like the following at the directed end (https://demo.abp.io/api/account/send-email-confirmation-token):
sendEmailConfirmationToken = (input: SendEmailConfirmationTokenDto, config?: Partial<Rest.Config>) =>
this.restService.request<any, void>({
method: 'POST',
url: '/api/app/custom-online-account/send-email-confirmation-token',
body: input,
,
{ apiName: this.apiName,...config });
In short, the confirmuser page isn't provided as a node in our abp angular package (api/account/send-email-confirmation-token).
https://demo.abp.io/Account/ConfirmUser This section isn't redirected to the frontend either.
5 Answer(s)
-
0
To address the issue of handling email confirmation and user ID retrieval in your ABP Angular application:
The ABP Angular package does not provide a built-in frontend route for the "ConfirmUser" page (e.g., /Account/ConfirmUser) or a direct API endpoint like /api/account/send-email-confirmation-token out of the box. This is why you do not see a redirect or a node for this in your Angular app.
When the login error indicates that the user must confirm their email, the backend should ideally return the userId in the error response. However, as you observed, this is not always the case, especially if the backend is not customized to include it.
To resolve this:
- Ensure your backend (AccountController or custom login endpoint) includes the userId in the error response when login fails due to unconfirmed email. This may require customizing the backend logic to add userId to the error payload.
- On the frontend, extract the userId from the error response as you attempted. If it is not present, you cannot proceed with sending the confirmation token without it.
To implement the email confirmation flow in Angular:
- Add a custom page/component for email confirmation (e.g., /account/confirm-user).
- When the login error indicates email confirmation is required, redirect the user to this page, passing the userId (if available).
- On this page, call your backend endpoint (e.g., /api/account/send-email-confirmation-token) with the userId to send the confirmation email.
If you want to configure the Angular app to handle the confirmation page and API:
- Add a route in your Angular routing module for the confirm-user page.
- Implement the logic to call the backend API and handle the confirmation process.
Example backend customization (C#):
// In your AccountController if (!user.EmailConfirmed) { return Unauthorized(new { error_description = "You are not allowed to login! Your account is inactive or needs to confirm your email/phone number.", userId = user.Id }); }
Example Angular error handling:
case "You are not allowed to login! Your account is inactive or needs to confirm your email/phone number.": const userId = err.error?.userId; if (userId) { this.router.navigate(['/account/confirm-user'], { queryParams: { userId } }); } break;
If the userId is not returned, you must update your backend to include it.
Sources:
- https://abp.io/support/questions/7608
- https://docs.abp.io/en/abp/latest/Modules/Account
- https://docs.abp.io/en/abp/latest/Emailing
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
-
0
Hello,
I have followed all the steps mentioned, but my problem still persists. Can I get support from a representative?
Sincerely.
-
0
Hello,
In ABP, two-factor authentication (2FA) is an optional security feature that must be enabled per user. When enabled, after the username and password are verified, the backend does not immediately log the user in. Instead, it responds with a
"RequiresTwoFactor"
error along with theuserId
andtwoFactorToken
. The frontend must then guide the user through the “send security code” and “verify security code” steps to complete login. You can refer to this document: https://abp.io/docs/latest/modules/identity/two-factor-authenticationNormally, 2FA depends on the user having a confirmed email address or phone number, because the second factor is delivered through those channels (or via an authenticator app tied to a confirmed identity).
Could you please clarify:
- How 2FA has been enabled for users who don’t have a confirmed email/phone?
- Is 2FA a feature you want us to implement fully in this project, or should we focus only on the email/phone confirmation flow for now?
Thank you for your cooperation.
-
0
Thank you for your answer, you may not have seen one of the section in the question: In short, the confirmuser page isn't provided as a node in our abp angular package (api/account/send-email-confirmation-token).
https://demo.abp.io/Account/ConfirmUser
This section isn't redirected to the frontend either.
Why does it work automatically on the Blazor side and not on the Angular side?
-
0
Thank you for your clarification.
The reason you see a difference between MVC and Angular is due to the authorization flow being used:
- MVC app uses the Authorization Code Flow.
- In this flow, the authentication happens on the server side.
- When the backend detects that the user’s email is not confirmed, it can directly redirect to the
/Account/ConfirmUser
page (server-side redirect). - That’s why it just works automatically in the MVC app.
- Angular app is a client-side SPA.
- If you use Resource Owner Password Flow, the login happens entirely on the Angular side.
- In this case, there is no server-side redirect — instead, the Angular client receives an error (e.g., inactive user / confirm email required), and it must decide how to handle it (e.g., call
/api/account/send-email-confirmation-token
and show a confirmation screen). - This is why the Angular package does not provide
/Account/ConfirmUser
out of the box.
In short:
- Code Flow = backend handles redirects (Blazor, MVC, Razor Pages).
- Password Flow = frontend must handle errors manually (Angular, SPA).
Here’s a reference explaining the difference between Code Flow and Password Flow in OAuth 2.0:
- MVC app uses the Authorization Code Flow.