Reputation: 86
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
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:
[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();
}
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.
[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
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
});
}
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