Tom*_*Tom 5 c# asp.net-core asp.net-core-webapi angular
语境
我们正在将使用 Asp.Net Core (Web Api) 的 Web 应用程序迁移到使用 Angular2 单页应用程序 (SPA) 前端。该应用程序最初是使用“个人用户帐户”进行的。我们已经将 cshtml 视图转换为 Angular2 组件,将控制器方法转换为生成 Json,甚至合并 JWT 进行身份验证。
我一直在使用这个配置谷歌身份验证微软文档。
问题
通过以下两种控制器方法说明了该问题。该LinkLogin方法返回一个ChallengeResult动作。显然这不能转换为 JSON。我认为这个结果应该会导致浏览器重定向到外部登录提供程序,然后自动重定向到LinkLoginCallback.
[HttpPost]
public async Task<IActionResult> LinkLogin([FromBody] string provider)
{
// Clear the existing external cookie to ensure a clean login process
await HttpContext.Authentication.SignOutAsync(externalCookieScheme);
// Request a redirect to the external login provider to link a login for the current user
string redirectUrl = Url.Action(nameof(LinkLoginCallback), "Manage");
var properties = signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, userManager.GetUserId(User));
return Challenge(properties, provider);
}
[HttpPost]
[Produces("application/json")]
public async Task<ActionResult> LinkLoginCallback()
{
User user = await userManager.GetUserAsync(User);
if (user == null)
return Json(false);
ExternalLoginInfo info = await signInManager.GetExternalLoginInfoAsync(await userManager.GetUserIdAsync(user));
if (info == null)
return Json(false);
IdentityResult result = await userManager.AddLoginAsync(user, info);
if (result.Succeeded)
{
// Clear the existing external cookie to ensure a clean login process
await HttpContext.Authentication.SignOutAsync(externalCookieScheme);
return Json(true);
}
return Json(false);
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试LinkLogin从 Angular 调用,我会收到以下响应:
对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问来源“ http://localhost:53462 ”。响应的 HTTP 状态代码为 405。
因此,我最终提出了一个解决方案,通过修改 Angular2 和 WebApi 之间的流程来避免“ChallengeResult”。
angular2-social-login到 Angular 应用程序中(遵循所有简单的设置说明)。将两种控制器方法合并为一种。该ExternalLoginViewModel参数是一个简单的类,具有 Email、ProviderKey 和 LoginProvider 属性(在步骤 3 中以 Angular 填充):
[HttpPost]
[Produces("application/json")]
public async Task<ActionResult> LinkLogin([FromBody] ExternalLoginViewModel info)
{
if (ModelState.IsValid)
{
User user = await userManager.GetUserAsync(User);
if (user != null)
{
IdentityResult result = await userManager.AddLoginAsync(user, new UserLoginInfo(info.LoginProvider, info.ProviderKey, info.LoginProvider));
if (result.Succeeded)
return Json(true);
}
}
return Json(false);
}
Run Code Online (Sandbox Code Playgroud)更改了 Angular2 客户端以使用社交媒体包来获取 Web API 所需的凭据。这是我LinkProvider演示连接的方法:(this.service.LinkLogin调用LinkLogin控制器方法)
public async LinkProvider(providerName: string): Promise<void>
{
const result: any = await this.auth.login(providerName).toPromise();
const success: boolean = await this.service.LinkLogin({
email: result.email,
loginProvider: result.provider,
providerKey: result.uid
});
// Handle link response here
}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
2136 次 |
| 最近记录: |