我有一个ASP.NET Core Web应用程序。用户可以登录,使用Identity。
我现在正在使用Xamarin构建一个Android应用程序,该应用程序将提供网站的缩小部分 - 从库存中添加/删除产品。
这是登录操作:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var result = await _signInManager.PasswordSignInAsync (model.Email, model.Password, model.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
var user = await UserManager.FindByNameAsync( model.Email );
if ( !user.IsApproved ) {
await _signInManager.SignOutAsync();
_logger.LogWarning(2, "User account not approved.");
return RedirectToAction("NotApproved");
}
AddAutoLogoutCookie();
_logger.LogInformation(1, "User logged in.");
return RedirectToLocal(returnUrl);
}
if (result.RequiresTwoFactor)
{
return RedirectToAction("VerifyCode", new { Provider = AppSettings.GoogleAuthenticatorProviderName, ReturnUrl = returnUrl, RememberMe = model.RememberMe });
}
if (result.IsLockedOut)
{
_logger.LogWarning(2, "User account locked out.");
return View("Lockout");
}
else
{
ModelState.AddModelError(string.Empty, _localizer["Incorrect creds"]);
return View(model);
}
}
那么,我可以使用它来将用户登录到Xamarin应用程序吗?我将如何粗略地处理这个问题?感谢。
答案 0 :(得分:8)
你的问题非常广泛,但我会尽力帮助。如果您有一个网站和一个移动应用程序访问同一个数据库并使用相同的业务逻辑我建议创建一个API,您的API应该处理身份验证和访问您的数据层并执行CRUD操作。它并不关心消耗它的东西(移动应用程序或网站)。
您的网站和移动应用会将请求发送到此API,API会相应地做出响应。处理您发送登录的授权,API将返回一个Json Web令牌或cookie(取决于您使用的内容)以及随后的请求,您将此令牌与请求一起发送。
使用Xamarin一个便携式类库是一个处理API消费的好地方,因为它可以在ios和android上重用。
如果您使用Json Web Tokens,您的Xamarin请求可能会是什么样子。
public async Task<HttpStatusCode> LoginAsync(CredentialModel credentialModel)
{
var uri = new Uri(UrlResourceNames.LoginUrl);
return await SendCredentialsAsync(credentialModel, uri);
}
private async Task<HttpStatusCode> SendCredentialsAsync(CredentialModel credentialModel, Uri uri)
{
var jsonProduct = JsonConvert.SerializeObject(credentialModel);
var httpContent = new StringContent(jsonProduct, Encoding.UTF8, "application/json");
var response = await _apiConnecter.PostRequest(uri, httpContent);
if (!response.IsSuccessStatusCode)
return response.StatusCode;
string responseJson = await response.Content.ReadAsStringAsync();
var tokenModel = JsonConvert.DeserializeObject<TokenModel>(responseJson);
Settings.JwtToken = tokenModel.Token;
Settings.JwtExpirationDate = tokenModel.Experation;
return response.StatusCode;
}
然后你的APIConnector可以处理对API的所有CRUD请求。在此示例中,APIConnector检查是否存在Json Web令牌,如果存在,则会发送包含所有请求的令牌(因为在此示例中,除登录和注册之外的所有请求都需要授权),然后API验证令牌。
public class APIConnecter
{
HttpClient _httpClient;
private string _jwtToken;
public APIConnecter()
{
_httpClient = new HttpClient();
ISettings _appSettings;
_appSettings = _appSettings = CrossSettings.Current;
_jwtToken = Settings.JwtToken;
if(!String.IsNullOrEmpty(_jwtToken))
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", _jwtToken);
}
public async Task<HttpResponseMessage> GetRequest(Uri uri)
{
var response = await _httpClient.GetAsync(uri);
return response;
}
public async Task<HttpResponseMessage> DeleteRequest(Uri uri)
{
var response = await _httpClient.DeleteAsync(uri);
return response;
}
public async Task<HttpResponseMessage> PostRequest(Uri uri, HttpContent content)
{
var response = await _httpClient.PostAsync(uri, content);
return response;
}
public async Task<HttpResponseMessage> PutRequest(Uri uri, HttpContent content)
{
var response = await _httpClient.PutAsync(uri, content);
return response;
}
}
您在api上的登录看起来像这样
public async Task<IActionResult> Login([FromBody] CredentialModel credentialModel)
{
var user = await _userManager.FindByEmailAsync(credentialModel.Email);
if (user == null)
return NotFound();
if (_hasher.VerifyHashedPassword(user, user.PasswordHash, credentialModel.Password) != PasswordVerificationResult.Success)
return Unauthorized();
var token = CreateToken(user);
if (token == null)
return StatusCode(500, "A problem happened while handling your request");
return Ok(new
{
token = new JwtSecurityTokenHandler().WriteToken(token),
experation = token.ValidTo
});
}