简体   繁体   中英

Angular 8 and Microsoft Login Identity User (dotnet Core 3.0 3.1)

Please bear with me since I am new to Angular and Identity User login process.

I have an Angular project with authentication user (login/logout, register and profile, etc.). The back end is an MSFT database backend to support these features.

I am able to add additional information to the registration process (LastName, FirstName, Gender, etc.).

Here is my problem: My Angular component or pages can not see the information this MSFT process. I have seen a process "private async Task LoadAsync(ApplicationUser user)" for example in the code but I don't know how initiate to call from Angular side (I believe it something like http://localhost:4200/area/Identity/page/account/manage ... Can it be done or I am way off the reality?

Please direct me to the right direction or a sample of code will be appreciated very much.

the code below is from ..\\Areas\\Identity\\Pages\\Account\\Manage\\index.cshtml.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using WebAngular.Models;

namespace WebAngular.Areas.Identity.Pages.Account.Manage
{
    public partial class IndexModel : PageModel
    {
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly SignInManager<ApplicationUser> _signInManager;

        public IndexModel(
            UserManager<ApplicationUser> userManager,
            SignInManager<ApplicationUser> signInManager)
        {
            _userManager = userManager;
            _signInManager = signInManager;
        }

        public string Username { get; set; }

        [TempData]
        public string StatusMessage { get; set; }

        [BindProperty]
        public InputModel Input { get; set; }

        public class InputModel
        {
            [Phone]
            [Display(Name = "Phone number")]
            public string PhoneNumber { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string MiddleName { get; set; }
            public string Gender { get; set; }
            public string AboutUser { get; set; }
            public DateTime BirthDate { get; set; }

        }

        private async Task LoadAsync(ApplicationUser user)
        {
            var userName = await _userManager.GetUserNameAsync(user);
            var phoneNumber = await _userManager.GetPhoneNumberAsync(user);

            Username = userName;

            Input = new InputModel
            {
                PhoneNumber = phoneNumber,
                LastName = user.LastName,
                FirstName = user.FirstName,
                Gender = user.Gender,
                AboutUser = user.AboutUser,
                BirthDate = user.BirthDate,
                MiddleName = user.MiddleName,
            };
        }

        public async Task<IActionResult> OnGetAsync()
        {
            var user = await _userManager.GetUserAsync(User);
            if (user == null)
            {
                return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
            }

            await LoadAsync(user);
            return Page();
        }

        public async Task<IActionResult> OnPostAsync()
        {
            var user = await _userManager.GetUserAsync(User);
            if (user == null)
            {
                return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
            }

            if (!ModelState.IsValid)
            {
                await LoadAsync(user);
                return Page();
            }

            var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
            if (Input.PhoneNumber != phoneNumber)
            {
                var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber);
                if (!setPhoneResult.Succeeded)
                {
                    var userId = await _userManager.GetUserIdAsync(user);
                    throw new InvalidOperationException($"Unexpected error occurred setting phone number for user with ID '{userId}'.");
                }
            }

            if (Input.BirthDate != user.BirthDate)
            {
                user.BirthDate = Input.BirthDate;
            }
            if (Input.FirstName != user.FirstName)
            {
                user.FirstName = Input.FirstName;
            }
            if (Input.LastName != user.LastName)
            {
                user.LastName = Input.LastName;
            }
            if (Input.AboutUser != user.AboutUser)
            {
                user.AboutUser = Input.AboutUser;
            }
            if (Input.Gender != user.Gender)
            {
                user.Gender = Input.Gender;
            }
            if (Input.MiddleName != user.MiddleName)
            {
                user.MiddleName = Input.MiddleName;
            }

            await _userManager.UpdateAsync(user);

            await _signInManager.RefreshSignInAsync(user);
            StatusMessage = "Your profile has been updated";
            return RedirectToPage();
        }
    }
}

I can display 'username' from the angular application.

import { Component, OnInit } from '@angular/core';
import { ConfigService, AppConfig } from '../services/config/config.service';
import { AuthorizeService } from '../../api-authorization/authorize.service';
import { Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
})
export class HomeComponent implements OnInit  {
  public isAuthenticated: Observable<boolean>;
  public userName: Observable<string>;
  public firstName: Observable<string>;
  appConfig: AppConfig;
  constructor(private appConfigProvider: ConfigService, private authorizeService: AuthorizeService) {
    appConfigProvider.loadConfig()
      .toPromise()
      .then(x => {
        this.appConfig = x;
      }
      );
    console.log(this.appConfig);
  }
  ngOnInit() {
    this.isAuthenticated = this.authorizeService.isAuthenticated();
    this.userName = this.authorizeService.getUser().pipe(map(u => u && u.name));
  }

}

Basically, there are API in the api-authorization directory which allows me call via javascript/typescript. However, I still not be able to display firstname, lastname etc. Can any one direct me to the right place (how to get user profile from angular)? Thanks.

It is hell for me to go thru login.html, login.csthml in areas, src/api-authorization in ClientApp.

Instead I have created a controller to pull data from sql server. It not to bad, it is used userManage object to pull data from. here is my code to do it (just in case someone tries to do it just like me).

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Identity;
using WebAngular.Models;
using Microsoft.AspNetCore.Authorization;
using System.Security.Claims;


namespace WebAngular.Controllers
{
    [ApiController]
    [Route("getUserProfileAsync")]
    public class UserProfileController : ControllerBase
    {
        private readonly UserManager<ApplicationUser> _userManager;
        public UserProfileController(UserManager<ApplicationUser> userManager)
        {
            _userManager = userManager;
        }

        [HttpGet]
        [Authorize]
        public async Task<object> Get()
        {
            string userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
            var user = await _userManager.FindByIdAsync(userId);
            var fullName = user.FirstName + ' ' + user.LastName;

            return Ok(new
            {
                user.Id,
                user.PhoneNumber,
                user.LastName,
                user.FirstName,
                user.MiddleName,
                user.Gender,
                user.AboutUser,
                user.BirthDate,
                fullName

            });
        }
    }

}

here are the codes in my Angular services

private profileUrl: string;
  constructor(private http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
    this.configUrl = baseUrl + 'config';
    this.profileUrl = baseUrl + 'getUserProfileAsync';
  }

and the method/function to get user profile:

 getUserProfile(): Observable<any> {
    return this.http.get<any>(this.profileUrl)
      .pipe(
        tap(() => console.log("HTTP request executed")),
        catchError(err => {
          console.log('Handling error locally and rethrowing it...', err);
          return throwError(err);
        }),
        finalize(() => console.log("second finalize() block executed"))
      );
  }

and the last piece... you need to put it in a component where you want to see the user profile

ngOnInit() {
    this.isAuthenticated = this.authorizeService.isAuthenticated();
    if (this.isAuthenticated) {
      this.appConfigProvider.getUserProfile()
        .toPromise()
        .then(x => {
          this.profile = x;
        }
        );

    }
  }

and in the component template (html):

<pre>
{{ profile | json  }}
</pre>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM