'How to return a cookie from an ASP.NET Core Auth Cookie in a Controller

I currently have a razor page where I return a cookie and it works great. However, I am developing a SPA which uses VueJS so I have created an API to directly communicate with. I have converted my code from the Razor Page to the controller but I am not sure how I actually return the cookie when the user tries to log in. If there is a match I want it to return the cookie and create the cookie. As of now I get a 400 code as if this request is not working. Any thoughts what could be wrong with this?

    public class LoginController : Controller
{

    private readonly LoginDBContext _context;
    private string connectionString;
    public IConfiguration Configuration { get; }

    public LoginController(LoginDBContext context, IConfiguration configuration)
    {
        _context = context;
        connectionString = configuration["ConnectionStrings:MMCARMSContext"];       
    }

    // GET: HomeController
    public ActionResult Index()
    {
        return Ok(new { Result = "Test" });
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login([FromForm] string Username, [FromForm] string Password, [FromForm] bool RememberMe)
    {
        if (!String.IsNullOrEmpty(Username) && !String.IsNullOrEmpty(Password))
        {
            var users = _context.UsersAccountsTbl
                .Where(a => a.Username == Username)
                .Select(a => new { a.InternalUserNumber, a.Username, a.Password })
                .ToArray();

            if (users.Length == 1) //if we have more than 1 result we have security issue so do not allow login
            {

                var passwordHasher = new PasswordHasher<string>();
                //To use you need to has with var hashedPassword = passwordHasher.HashPassword(UserName, Password);
                //System.Diagnostics.Debug.WriteLine(passwordHasher.HashPassword("Username", "password"));
                var user = users.First();

                if (passwordHasher.VerifyHashedPassword(user.Username, user.Password, Password) == PasswordVerificationResult.Success)
                {
                    var claims = new List<Claim>
                    {
                        new Claim(ClaimTypes.Name, user.InternalUserNumber.ToString())
                    };

                    var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);

                    if (RememberMe)
                    {
                        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
                            new ClaimsPrincipal(claimsIdentity),
                            new AuthenticationProperties
                            {
                                IsPersistent = RememberMe,
                                ExpiresUtc = DateTimeOffset.UtcNow.AddHours(2)
                            });
                    }
                    else
                    {
                        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
                            new ClaimsPrincipal(claimsIdentity));
                    }
                    return Ok(new { Result = "Cookie has been created!" });
                }
                else
                {
                    return Ok(new { Result = "Password is incorrect!" });
                }

            }

            return Ok(new { Result = "Username or Password does not exist!" });
        }
        else
        {
            return Ok(new { Result = "Username or Password invalid!" });
        }
    }
}


Solution 1:[1]

You could set the cookie in the HttpResponse, this way the cookie gets added when the client receives the response from your controller:

HttpCookie MyCookie = new HttpCookie("LastVisit");
DateTime now = DateTime.Now;

MyCookie.Value = now.ToString();
MyCookie.Expires = now.AddHours(1);

Response.Cookies.Add(MyCookie);

https://docs.microsoft.com/en-us/dotnet/api/system.web.httpresponse.cookies?view=netframework-4.8

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Fy Z1K