indra257
indra257

Reputation: 86

Getting the logged in user in to the Angular 2 application from an .NET platform

I am building a new Angular2 application and it will reside inside an .NET application platform. My Angular2 application should get the current logged in user to make the API calls to fetch the data. How can I get the userId in to my app.

Upvotes: 4

Views: 12193

Answers (1)

GeorgDangl
GeorgDangl

Reputation: 2192

Since you didn't explicitly specify what .Net platform you're using, I'm going to assume it's the most recent one - Asp.Net Core with Asp.Net Identity as authentication provider.

If you're using the default Asp.Net Identity template, you can simply use cookie based authentication for your web api requests. The cookies are automatically passed by your browser to the server when you make calls via Angular 2s http service, so you don't need to specify anything explicit there.

Here's some minimal code that could do what you want:

Login method in your server side controller

[HttpPost("Login")]
public async Task<IActionResult> Login([FromBody] LoginPost model)
{
    if (ModelState.IsValid)
    {
        // Require the user to have a confirmed email before they can log on.
        var user = await _userManager.FindByEmailAsync(model.Email);
        if (user != null)
        {
            var result = await _signInManager.PasswordSignInAsync(user, model.Password, model.StayLoggedIn, lockoutOnFailure: false);
            if (result.Succeeded)
            {
                return Ok();
            }
        }
    }
    return BadRequest();
}

Angular 2 service method to perform the login

This is called from your login component, e.g. the component that hosts your login form.

public login(email: string, password: string, stayLoggedIn: boolean): Promise<boolean> {
    var url = '/Api/Account/Login';
    var loginCredentials = {
        email: email,
        password: password,
        stayLoggedIn: stayLoggedIn
    };
    return this.http
        .post(url, loginCredentials)
        .toPromise()
        .then(response => {
            return response.ok;
        })
        .catch(() => {
            return false;
        });
}

Upon successful login, _signInManager.PasswordSignInAsync() will set a cookie on the client that's automatically validated by the framework for further requests.

User details method server side

[HttpGet("Auth")]
public async Task<IActionResult> Auth()
{
    var model = new AuthGet();
    if (!User.Identity.IsAuthenticated)
    {
        model.IsAuthenticated = false;
        return Ok(model);
    }
    var user = await _userManager.GetUserAsync(User);
    var roles = await _userManager.GetRolesAsync(user);
    model.Username = user.UserName;
    model.IsAuthenticated = true;
    model.Id = user.Id;
    model.Email = user.Email;
    model.Roles = roles;
    return Ok(model);
}

This is just some server side code that returns basic information about the currently logged in user

Making this info available in your client side code

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Http } from '@angular/http';
import { Auth } from '../Models/Account/auth';

@Injectable()
export class AuthService {

    private authSource = new BehaviorSubject<Auth>(new Auth);
    public auth = this.authSource.asObservable();

    constructor(private http: Http) {
        this.updateAuth();
    }

    public updateAuth() {
            var url = '/Api/Account/Auth';
            this.http
                .get(url)
                .toPromise()
                .then(response => {
                    var auth = response.json() as Auth;
                    this.authSource.next(auth);
                });
    }
}

This AuthService now offers an Observable that you can subscribe to in your components, e.g. for example like this:

private auth: Auth;
private authSubscription: Subscription;

ngOnInit() {
    this.updateProfileOverview();
    this.authSubscription = this.authService.auth.subscribe(newAuth => {
        this.auth = newAuth;
        // React to the new auth value 
    });
}

Getting the UserId in your server side controllers

Now that requests are being automatically authenticated by the framework, you can make use of Asp.Net Identity's UserManager by injecting it in your controller and using it to get the user id like this:

namespace App.Controllers
{
    public class DataController : Controller
    {
        public NotesController(UserManager<ApplicationUser> userManager)
        {
            _userManager = userManager;
        }

        private readonly UserManager<ApplicationUser> _userManager;

        public async Task<IActionResult> CreateNote()
        {
            var userId = _userManager.GetUserId(User);
            // Use it...
        }
    }
}

The User property is present on all classes derived from the base Controller class.

Upvotes: 6

Related Questions