无法从Docker容器打开URL [英] Can't open URL from a docker container

查看:270
本文介绍了无法从Docker容器打开URL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法从Docker容器导航到Google身份验证页面.该应用程序是使用asp.net Core 2.0制作的,其目的是显示从Google Calendar API检索到的即将发生的事件,并在需要时创建事件.

I'm having trouble with navigating to Google Authentication page from a docker container. The app is made using the asp.net Core 2.0 and it's purpose is to show upcoming events retrieved from Google Calendar API, and also to create events if needed.

该应用未从Docker容器运行时可按预期运行, 会生成授权码请求URL,并且基于环境(Windows,Linux或OSX),应用程序尝试使用OpenBrowser方法中的Process.start()打开URL.

The app works as expected when it's not running from a docker container, Authorization Code request URL is generated and based on the environment (Windows, Linux or OSX) the app tries to open the URL with Process.start() inside OpenBrowser method.

private bool OpenBrowser(string url)
    {
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
        {
            url = System.Text.RegularExpressions.Regex.Replace(url, @"(\\*)" + "\"", @"$1$1\" + "\"");
            url = System.Text.RegularExpressions.Regex.Replace(url, @"(\\+)$", @"$1$1");
            Process.Start(new ProcessStartInfo("cmd", $"/c start \"\" \"{url}\"") { CreateNoWindow = true });
            return true;
        }
        if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
        {
            Process.Start("xdg-open", url);
            return true;
        }
        if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
        {
            Process.Start("open", url);
            return true;
        }
        return false;
    }

成功打开浏览器后,用户需要输入其Google帐户凭据并登录以接收用于创建令牌的授权代码.

When the browser is successfully opened, the user needs to enter his Google Account credentials and sign in to receive the authorization code used for creating token.

public async Task<AuthorizationCodeResponseUrl> ReceiveCodeAsync(AuthorizationCodeRequestUrl url, CancellationToken taskCancellationToken)
    {
        var authorizationUrl = url.Build().AbsoluteUri;
        using (var listener = StartListener())
        {
            bool browserOpenOk;
            try
            {
                browserOpenOk = OpenBrowser(authorizationUrl);
            }
            catch (Exception e)
            {
                Logger.Error(e, "Failed to launch browser with \"{0}\" for authorization", authorizationUrl);
                throw new NotSupportedException(String.Format("Failed to launch browser with \"{0}\" for authorization. See inner exception for details.", authorizationUrl, e));
            }
            var ret = await GetResponseFromListener(listener, taskCancellationToken).ConfigureAwait(false);

            s_receivedCallback = true;

            return ret;
        }
    }

我的猜测是linux docker容器没有打开URL所必需的工具,这就是导致此问题的原因.我的问题是,有人可以告诉我如何转发要在主机上而不是在容器内打开的URL,或者如何在不尝试从docker容器打开URL的情况下获取令牌?

My guess is that the linux docker container doesn't have the necessary tool to open the URL and that's what's causing the issue. My question is, can somebody tell me how can I forward the URL to open on the host and not inside the container, or how can I get the token without trying to open url from the docker container?

默认情况下,Google使用这种方式对用户进行身份验证(通过使用Process.start打开url),并且还打开了随机端口以侦听身份验证响应代码,因此我必须创建自己的类来实现ICodeReceiver,因为docker要求精确在容器内运行映像之前要指定的端口.

Google by default uses that way of authenticating users (by opening url with Process.start), and also opens random port to listen for authentication response code, so I had to create my own class which implements ICodeReceiver, because docker requires exact ports to be specified before running an image inside a container.

推荐答案

我在编写python脚本并将其打包到docker映像中时遇到了同样的问题. 我发现的唯一解决方案是将以下行添加到参数noauth_local_webserver = True.

I had the same problem writing a python script and packing it into a docker image. The only solution I found was to add the following line to the arguments noauth_local_webserver = True.

这是python中的示例代码:

This is the sample code in python:

if not creds or creds.invalid:
    flow = client.flow_from_clientsecrets('.client_secret.json', SCOPES)
    args = tools.argparser.parse_args()
    args.noauth_local_webserver = True
    creds = tools.run_flow(flow, store, args)
    service = build('sheets', 'v4', http=creds.authorize(Http()))
else:
    service = build('sheets', 'v4', http=creds.authorize(Http()))

使用该选项,它将打印一个URL,您可以将该URL复制到任何Web浏览器中,并且在身份验证之后,它会生成一个需要复制到终端中的代码.

With that option it prints an URL that you can copy into any web browser and after the authentication it generates a code that you need to copy into the terminal.

这篇关于无法从Docker容器打开URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆