Reputation: 4503
I have created a controller for Login and there is an endpoint for authentication. I am using Microsoft.AspNetCore.Identity;
Here is the code for this controller
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
[Route("api/[controller]")]
[ApiController]
public class LoginController : ControllerBase
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
public LoginController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
}
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> LoginAsync([FromBody] LoginRequest userLogin)
{
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync(userLogin.Username, userLogin.Password, isPersistent: false, lockoutOnFailure: false);
if (result.Succeeded)
{
// code removed for brevity
}
}
return BadRequest();
}
}
How do I get the bearer token from result
? I wish to return back the token bearer as a response if /api/Login post request is successful.
Upvotes: 4
Views: 5383
Reputation: 596
If you can update your project to asp.net core 8 best solution will be using Identity API endpoints. This is an identity endpoint example. If you still want to keep your implementation on top of asp.net core identity this example has complete extendable code with react. Source Tutorial
Upvotes: 1
Reputation: 300
Depending how you want the client to store the token. If you want to deal with it in the client side you can Return Ok(result.generatedToken)
but if you want to set it as a cookie I would recommend you to just Return Ok() but before that you set the cookie in the header of the response. You do this in the server
// append cookie with token to the http response
CookieOptions? cookieOptions = new()
{
HttpOnly = true,
SameSite = SameSiteMode.Strict,
Secure = true,
Expires = ExpirationDate //it has to be a DateTime
};
Response.Cookies.Append("token", token, cookieOptions);
the advantage of doing it from the server is that you protect the token from being stolen by XSS injection or other attacks since the token is not accessable from javascript and can only be used in HTTPrequests.
Upvotes: 0
Reputation: 3956
SignInManager<TUser>.PasswordSignInAsync
Method Attempts to sign in the specified userName and password combination as an asynchronous operation and return Task<SignInResult>
. for bearer token use CheckPasswordAsync
.
its return a flag indicating whether the given password is valid for the specified user.
_userManager.CheckPasswordAsync(user, model.Password)
if user has valid creadintial then generate the token.
if (user != null && await _userManager.CheckPasswordAsync(user, model.Password))
{
var userRoles = await _userManager.GetRolesAsync(user);
var authClaims = new List<Claim>
{
new Claim(ClaimTypes.Name, user.UserName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
foreach (var userRole in userRoles)
{
authClaims.Add(new Claim(ClaimTypes.Role, userRole));
}
var token = GetToken(authClaims);
return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
expiration = token.ValidTo
});
}
Ref: Link1, Link2, Link3, Link4
Upvotes: 7