PWA: заставить window.open открывать браузер вместо PWA - PullRequest
0 голосов
/ 06 марта 2020

Я создал ядро ​​ASP. NET с интерфейсом angular. Приложение angular имеет настройку пакета узла @angular/pwa, так что это прогрессивное веб-приложение, которое может быть установлено на Android / windows и ведет себя как нативное приложение.

У меня настроен внешний вход (Microsoft, Google, Facebook, Twitter) с Microsoft.AspNetCore.Identity. Из моего приложения angular я открываю всплывающее окно на страницу внешнего входа:

  this.authWindow = window.open(`${this.baseUrl}/web/v2/Account/${this.action}/${medium}/${this.platform}`, null, 'width=600,height=400');

URL-адрес для всплывающих маршрутов к конечной точке ASP. NET Core, где у меня есть * 1007. * call, который возвращает страницу входа для указанного c внешнего провайдера (Microsoft, Google, Facebook, Twitter).

В Chrome на Windows, вы нажимаете кнопку, которая вызывает окно. open (), чтобы открыть окно с внешней страницей входа. При успешном входе в систему вы будете перенаправлены на страницу обратного вызова, которая является страницей бритвы, которая отправляет сообщение в главное окно, содержащее приложение angular. Сообщение обрабатывается, а всплывающее окно закрывается.

Проблема

Когда я использую веб-сайт на Chrome для Android, я могу установить PWA как приложение, которое добавляет значок на моей android домашней странице. Когда я открываю PWA и нажимаю кнопку, чтобы открыть всплывающее окно, всплывающее окно открывается во всплывающем окне для моего PWA, поэтому никаких проблем нет.

Когда я открываю Chrome на android и посещаю веб-сайт, в то время как PWA установлен, вызов window.open() не открывает всплывающее окно для браузера Chrome, но вместо этого пытается открыть всплывающее окно для Progressive Web App. Поскольку это так, всплывающее окно внутри PWA не может уведомить веб-сайт в Chrome об успешном входе в систему (дух ...).

Но когда PWA не установлен, window.open() работает в порядке и открывает всплывающее окно в Chrome.

Таким образом, нижняя строка - , PWA установлен на android. И я хочу иметь возможность звонить по номеру window.open() со своего веб-сайта внутри Chrome и открыть его в Chrome браузере вместо PWA.

Things I ' мы пробовали

1) Изменить ngsw-config. json

{
  ...,
  "navigationUrls": [
    "/**",
    "!/**/*.*",
    "!/**/*__*",
    "!/**/*__*/**",
    "!/web/v2/Account/connect/**/**",
    "!/web/v2/Account/add/**/**"
  ]
}

2) Открыть окно с помощью target='_system'

this.authWindow = window.open(`${this.baseUrl}/web/v2/Account/${this.action}/${medium}/${this.platform}`, '_system', 'width=600,height=400');

3) Открыть окно с target='_blank'

this.authWindow = window.open(`${this.baseUrl}/web/v2/Account/${this.action}/${medium}/${this.platform}`, '_blank', 'width=600,height=400');

4) Откройте окно с target='_blank' и без baseUrl, просто абсолютный путь.

this.authWindow = window.open(`/web/v2/Account/${this.action}/${medium}/${this.platform}`, '_blank', 'width=600,height=400');

Но все трюки, кажется, ведут себя одинаково и до сих пор откройте окно в PWA.

1 Ответ

0 голосов
/ 04 мая 2020

Я закончил тем, что создал поддомен, содержащий мои конечные точки для внешнего входа в систему (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).

...