如何使用ASP.NET Core后端在本地进行身份验证/授权

时间:2020-11-03 08:27:21

标签: react-native asp.net-core authentication authorization

我在MVC项目中将身份验证和授权实现为here。我有一个允许身份验证和授权的帐户控制器:

 public class AccountController : Controller
{
    private UsersContext db;
    public AccountController(UsersContext context)
    {
        db = context;
    }

    [HttpGet]
    public IActionResult Login()
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(LoginModel model)
    {
        if (ModelState.IsValid)
        {
            User user = await db.Users.FirstOrDefaultAsync(u => u.PhoneNumber == model.PhoneNumber && u.Password == model.Password);
            if (user != null)
            {
                await Authenticate(model.PhoneNumber); // аутентификация

                return RedirectToAction("Index", "Home");
            }
            ModelState.AddModelError("", "Некорректные логин и(или) пароль");
        }
        return View(model);
    }

    [HttpGet]
    public IActionResult Register()
    {
        return View();
    }
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Register(RegisterModel model)
    {
        if (ModelState.IsValid)
        {
            User user = await db.Users.FirstOrDefaultAsync(u => u.PhoneNumber == model.PhoneNumber);
            if (user == null)
            {
                // добавляем пользователя в бд
                db.Users.Add(new User { PhoneNumber = model.PhoneNumber, Password = model.Password });
                await db.SaveChangesAsync();

                await Authenticate(model.PhoneNumber); // аутентификация

                return RedirectToAction("Index", "Home");
            }
            else
                ModelState.AddModelError("", "Некорректные логин и(или) пароль");
        }
        return View(model);
    }

    private async Task Authenticate(string phone)
    {
        // создаем один claim
        var claims = new List<Claim>
        {
            new Claim(ClaimsIdentity.DefaultNameClaimType, phone)
        };
        // создаем объект ClaimsIdentity
        ClaimsIdentity id = new ClaimsIdentity(claims, "ApplicationCookie", ClaimsIdentity.DefaultNameClaimType, ClaimsIdentity.DefaultRoleClaimType);
        // установка аутентификационных куки
        await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(id));
    }

    public async Task<IActionResult> Logout()
    {
        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        return RedirectToAction("Login", "Account");
    }
}

它将身份验证数据保存在Cookie中。一切正常。在本机应用程序中使用此功能的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

“具有ASP.NET核心”对于您的问题没有多说... 我的意思是: 前端客户端和后端.net核心是不同的事物,并且一个不会影响另一个...。 由于您正在服务器上使用Cookie处理auth,因此在客户端上唯一要做的就是:

  1. 在身份验证响应上,读取cookie并在您的应用程序状态下保留声明,名称,id,角色等(请看here
  2. 确保所有请求也都发送出cookie(无论如何,默认情况下,这将在所有浏览器中完成。
  3. 在应用内进行路由时,请检查用户是否具有所需的声明

现在,由于您使用的是React应用,所以我建议您使用JWT令牌而不是Cookie,只是为了在整个应用程序中实施无状态性,因此Cookie并不适合这样做。 同样,如果您在哪里使用JWT:

  1. 后端是一回事,您的调用将保留在API中,但它们会向调用者提供令牌等,而不是响应中的cookie。
  2. 阅读JWT,将声明存储在应用状态中,并使用路由(例如,路由)来检查呼叫的身份验证/授权状态。
  3. 请确保在每个请求的标头中都提供了令牌,这通常是通过您的应用手动完成的,浏览器不会处理这部分通信。

还有另一个要点: 您正在构建SPA还是正在构建MVC解决方案? 您所指出的指南围绕着一个mvc项目,您不应该为react应用(通常是spa)遵循相同的指导... 建议您立即查看this

答案 1 :(得分:0)

我认为,对于使用REST API的基于浏览器的前端应用程序,最常见的方法是采用基于令牌的身份验证,该身份验证依赖于OAuth 2.0协议来执行令牌的实际发行。另外,您应该旨在将令牌发行委托给第三方(例如:IdentityServer4),这样您就不需要实现或维护系统的那部分,只需要使用/验证生成的令牌。您可以查看以下文章:

Authentication and authorization for SPAs

Using SPA (React/Angular) UI with Identity Server 4