我最终创建了一个托管我的端点以进行外部登录的子域(ExternalLogin
, ExternalLoginCallback
, AddExternalLogin
, AddExternalLoginCallback
):
[Controller]
[Route("web/v2/[controller]")]
public class AccountController : Controller
{
private IAccountService accountService;
public AccountController(IAccountService accountService)
{
this.accountService = accountService;
}
...
// GET: web/Account/providers
[AllowAnonymous]
[HttpGet("providers", Name = "web-v2-account-external-providers")]
public async Task<ActionResult<IEnumerable<string>>> Providers()
{
var result = await accountService.GetProviders();
return Ok(result);
}
// GET: web/Account/connect/{provider}
[AllowAnonymous]
[HttpGet("connect/{medium}/{provider}", Name = "web-v2-account-external-connect-challenge")]
#if RELEASE
[Host("external.mintplayer.com")]
#endif
public async Task<ActionResult> ExternalLogin([FromRoute]string medium, [FromRoute]string provider)
{
var redirectUrl = Url.RouteUrl("web-v2-account-external-connect-callback", new { medium, provider });
var properties = await accountService.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
}
// GET: web/Account/connect/{provider}/callback
[HttpGet("connect/{medium}/{provider}/callback", Name = "web-v2-account-external-connect-callback")]
#if RELEASE
[Host("external.mintplayer.com")]
#endif
public async Task<ActionResult> ExternalLoginCallback([FromRoute]string medium, [FromRoute]string provider)
{
try
{
var login_result = await accountService.PerfromExternalLogin();
if (login_result.Status)
{
var model = new LoginResultVM
{
Status = true,
Medium = medium,
Platform = login_result.Platform
};
return View(model);
}
else
{
var model = new LoginResultVM
{
Status = false,
Medium = medium,
Platform = login_result.Platform,
Error = login_result.Error,
ErrorDescription = login_result.ErrorDescription
};
return View(model);
}
}
catch (OtherAccountException otherAccountEx)
{
var model = new LoginResultVM
{
Status = false,
Medium = medium,
Platform = provider,
Error = "Could not login",
ErrorDescription = otherAccountEx.Message
};
return View(model);
}
catch (Exception ex)
{
var model = new LoginResultVM
{
Status = false,
Medium = medium,
Platform = provider,
Error = "Could not login",
ErrorDescription = "There was an error with your social login"
};
return View(model);
}
}
// GET: web/Account/logins
[Authorize]
[HttpGet("logins", Name = "web-v2-account-external-logins")]
public async Task<ActionResult<IEnumerable<string>>> GetExternalLogins()
{
var logins = await accountService.GetExternalLogins(User);
return Ok(logins.Select(l => l.ProviderDisplayName));
}
// GET: web/Account/add/{provider}
[Authorize]
[HttpGet("add/{medium}/{provider}", Name = "web-v2-account-external-add-challenge")]
#if RELEASE
[Host("external.mintplayer.com")]
#endif
public async Task<ActionResult> AddExternalLogin([FromRoute]string medium, [FromRoute]string provider)
{
var redirectUrl = Url.RouteUrl("web-v2-account-external-add-callback", new { medium, provider });
var properties = await accountService.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
return Challenge(properties, provider);
}
// GET: web/Account/add/{provider}/callback
[Authorize]
[HttpGet("add/{medium}/{provider}/callback", Name = "web-v2-account-external-add-callback")]
#if RELEASE
[Host("external.mintplayer.com")]
#endif
public async Task<ActionResult> AddExternalLoginCallback([FromRoute]string medium, [FromRoute]string provider)
{
try
{
await accountService.AddExternalLogin(User);
var model = new LoginResultVM
{
Status = true,
Medium = medium,
Platform = provider
};
return View(model);
}
catch (Exception)
{
var model = new LoginResultVM
{
Status = false,
Medium = medium,
Platform = provider,
Error = "Could not login",
ErrorDescription = "There was an error with your social login"
};
return View(model);
}
}
}
在 PWA 中运行时,window.open
仍会在 PWA 内的嵌入式浏览器内打开链接,并且从浏览器运行时window.open
仍会在新的浏览器窗口(而不是在 PWA 中)打开链接。在这两种情况下,我仍然可以访问开启器来发送消息(window.opener.postMessage
).