如何使用 ASP.NET 核心后端在 react-native 中做 Authentication/Authorization

How to do Authentication/Authorization in react-native with ASP.NET Core backend

我在我的 MVC 项目中实现了身份验证和授权 https://metanit.com/sharp/aspnet5/15.1.php。我有一个允许身份验证和授权的帐户控制器:

 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中保存认证数据。它工作正常。在 react-native 应用程序中使用它的最佳方式是什么?

“with ASP.NET core”并不能说明你的问题... 我的意思是: 前端客户端和后端.net core 是不同的东西,一个不影响另一个.... 由于您在服务器上使用 cookie 处理身份验证,因此在客户端上唯一要做的就是:

  1. 在身份验证响应中,读取 cookie 并在您的应用程序状态中保存声明、名称、ID、角色等(查看 here
  2. 确保所有请求也发送 cookie(默认情况下所有浏览器都会这样做。
  3. 在应用内路由时,检查用户是否有所需的声明

现在,由于您使用的是 React 应用程序,我建议使用 JWT 令牌而不是 cookie,这样您就可以在整个应用程序中强制执行无状态,cookie 对此并不适用。 同样,如果您在哪里使用 JWT:

  1. 后端是一个独立的东西,您的调用将保持在 API 中,但它们会向调用者提供令牌等,而不是响应中的 cookie。
  2. 读取 JWT,将声明存储在应用程序状态中,并使用(例如路由)来检查 authent/authorization 调用状态。
  3. 确保在每个请求的 header 中提供令牌,这通常是从您的应用手动完成的,浏览器不处理这部分通信。

还有一个重点: 您是在构建 SPA 还是在构建 mvc 解决方案? 您指出的指南围绕一个 mvc 项目展开,您不应该遵循与反应应用程序相同的指南,这通常是一个 spa ... 我建议你马上去this看看!

在我看来,对于 front-end browser-based 应用程序与 REST API 通信,最常见的方法是使用依赖于 OAuth 的 token-based 身份验证2.0 协议执行代币的实际发行。此外,您的目标应该是将代币发行委托给 third-party(例如:IdentityServer4),这样您就不需要实施或维护该部分系统,而只需要 consume/validate 生成的令牌。您可以查看以下文章:

Authentication and authorization for SPAs

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