在公司代理.pac后面使用npm

183

我需要通过npm下载几个包,但我们公司的代理配置是.pac文件(我在Windows上)

我已经尝试过:

npm config set proxy http://mydomain\username:password@1.2.3.4:8181/proxy.pac
npm config set https-proxy http://mydomain\username:password@1.2.3.4:8181/proxy.pac
或者
npm config set proxy http://1.2.3.4:8181/proxy.pac
npm config set https-proxy http://1.2.3.4:8181/proxy.pac

但它不起作用...

有什么建议吗?谢谢。


1
可能是重复的问题,参考有没有办法让npm install命令在代理后面工作? - Sriram
11
我认为这个问题不是重复的,PAC脚本可以根据目标IP/主机地址包含多个代理地址,而Dube只能使用一个代理地址。- 来自评论 - Ferrybig
1
没有一个答案表明如何使用可以包含多个代理地址的PAC脚本,这取决于目标IP/主机地址。有人能帮忙吗? - Partha Sarathi Ghosh
2
对我来说,打开 proxy.pac 文件以从中获取代理地址很有帮助。(在我的情况下,我只需要将端口切换到 8080)。 - sakura-bloom
1
@ParthaSarathiGhosh 你说得对,没错。事实上,没有任何答案能够真正解释如何使用PAC脚本,所以我添加了另一个答案来解决这个问题: https://dev59.com/1F8e5IYBdhLWcg3whqrl#61811444。虽然有些晚了,但总比从未开始好。 - user1031921
28个回答

226

我曾遇到一个非常类似的问题,我的npm无法在代理服务器后面工作。

我的用户名是“domain\username”的形式 - 在代理配置中包括斜杠会导致出现正斜杠。因此,输入以下内容:

npm config set proxy "http://domain\username:password@servername:port/"

然后运行 npm config get proxy 命令会返回如下结果: http://domain/username:password@servername:port/

因此为了解决问题,我使用URL编码替代了反斜杠,输入了以下内容:

npm config set proxy "http://domain%5Cusername:password@servername:port/"

代理访问问题得到了解决。


5
这是因为你遗漏了 %5C 这一部分,.key 是关键的部分,其中包含字母 C。看到你有点困惑,所以我把它分开写了。 - sinisterrook
1
我刚刚更新了一些东西,我的代理又停止工作了。原来在.npmrc文件的“proxy”设置中(如@Ovidiu Buligan所提到的),它包含了%5C表示反斜杠,但是“https-proxy”只包含了“\”。将其更改为也是%5C即可解决问题。我认为也可以通过运行**npm config set http_proxy "http://domain% 5Cusername:password@servername:port/"**来更新。 - Steve Roberts
1
我正在尝试在代理后面配置npm,但有一种使用npm配置进行“ping”的方法。因为如果我的配置不正确,我的用户将被阻止在我的公司域上。 - Ricardo Cunha
4
对我有效的方法是首先清除该死的环境变量。使用**set HTTP_PROXY=set HTTPS_PROXY=**。 - Sydwell
7
strict-ssl=false 添加到 .npmrc 配置文件中可解决在公司代理后的问题 - 参见 @ovidiu-buligan@karthikeyan-a 的回答。 - Alexander McFarlane
显示剩余11条评论

68

在Internet Explorer的局域网设置中查找pac文件的URL,并从配置的URL下载pac文件。

pac文件只是一个具有名为FindProxyForURL的函数的javascript文件,该函数在不同情况下返回不同的代理主机。

尝试在pac文件中找到一个你认为用于普通Web流量的主机,并将其插入到C:\Users\\.npmrc中。

proxy=http://<username>:<pass>@proxyhost:<port>
https-proxy=http://<uname>:<pass>@proxyhost:<port>

即使您可以在公司计算机上使用您的域名和用户名登录,代理可能仅需要用户名和密码(可能与您的Active Directory登录不同),而不需要用户活动目录域名。

不要忘记处理转义特殊密码字符。


59

下载你的.pac文件。在任何编辑器中打开它,查找PROXY = "PROXY X.X.X.X:80;。你可能有很多代理服务器,复制其中任何一个并运行以下终端命令:

npm config set proxy http://X.X.X.X:80
npm config set https-proxy http://X.X.X.X:80

现在您应该能够安装任何软件包!


1
对于https代理部分,我不得不执行"... set https-proxy=http://..."而不是"... set https-proxy http://..."才能使其工作。这只是我的个人意见。 - Nick
1
感谢将 https-proxy 设置为 http://,这是唯一有效的方法;在我从 bash 中取消 http_proxy 和 https_proxy 环境变量之后! - Alex Punnen
对于 https-proxy,我无法设置为 "set https-proxy https:/.../",而是必须设置为 "set https-proxy http://..."(代理信息从 https -> http)。 - Mars
1
同样适用于git, git config --global http.proxy http://X.X.X.X:80 git config --global https.proxy http://X.X.X.X:80 - Code Name Jack

42
我用以下方法解决了这个问题:
1) 运行以下命令:
``` npm config set strict-ssl false ```
2) 然后将 npm 设置为使用 http 而不是 https 运行:
``` npm config set registry "http://registry.npmjs.org/" ```
3) 最后安装你的包:
``` npm install ```

3
只是想指出,将npm的__strict-ssl__设置为__false__是一个安全问题。相反,考虑正确设置npm上的ca[]属性。 - Aaron C

31

为了进一步解释@Steve Roberts的回答。

我的用户名是以“domain\username”的形式命名的——在代理配置中包括斜杠会导致出现前向斜杠。因此,输入以下内容:

npm config set proxy "http://domain\username:password@servername:port/"
我还必须对我的domain\user字符串进行URL编码,但是我的用户名中有一个空格,因此我放了一个+来编码空格的URL编码,但它会被双重编码为%2B(这是加号的URL编码,但空格的URL编码是%20),因此我不得不改为执行以下操作:

npm命令

// option one 
// it works for some packages
npm config set http_proxy "http://DOMAIN%5Cuser+name:password@x.x.x.x:port"
npm config set proxy "http://DOMAIN%5Cuser+name:password@x.x.x.x:port"

// option two
// it works best for me
// please notice that I actually used a space 
// instead of URL encode it with '+', '%20 ' OR %2B (plus url encoded)
npm config set http_proxy "http://DOMAIN%5Cuser name:password@x.x.x.x:port"
npm config set proxy "http://DOMAIN%5Cuser name:password@x.x.x.x:port"

// option two (B) as of 2019-06-01
// no DOMAIN
// instead of URL encode it with '+', '%20 ' OR %2B (plus url encoded)
npm config set http_proxy "http://user name:password@x.x.x.x:port"
npm config set proxy "http://user name:password@x.x.x.x:port"

故障排除npm配置

我使用npm config list获取我之前设置的解析值,这就是我发现双重编码问题的方式。很奇怪。

实质上,您必须确定以下要求:

  1. 是否需要进行身份验证的DOMAIN字符串
  2. 您是否需要对特殊字符进行编码?
    • 空格和at(@)符号尤其具有挑战性

祝好。

WINDOWS环境变量(CMD提示符)

更新

事实证明,即使有了上述配置,我仍然在使用Request - Simplified HTTP client下载一些东西时,仍然存在一些包/脚本的问题。因此,如上面的自述文件所解释的那样,我们可以指定环境变量在命令行上设置代理,而请求将尊重这些值。

然后,在经过(我不愿意承认这一点)若干次尝试(更像是几天时间)之后,我终于成功地按照以下准则设置了环境变量:

rem notice that the value after the = has no quotations
rem    - I believe that if quotations are placed after it, they become
rem    part of the value, you do not want that
rem notice that there is no space before or after the = sign
rem     - if you leave a space before it, you will be declaring a variable 
rem     name that includes such space, you do not want to do that
rem     - if you leave a space after it, you will be including the space
rem     as part of the value, you do not want that either
rem looks like there is no need to URL encode stuff in there
SET HTTP_PROXY=http://DOMAIN\user name:password@x.x.x.x:port
SET HTTPS_PROXY=http://DOMAIN\user name:password@x.x.x.x:port

cntlm

I used this method for a few weeks, but then realized it was too cumbersome to update my password across all the tools that needed the proxy setup. Besides npm, I also use bower, vagrant (with virtual box running Linux), git, vscode, brackets, atom, and tsd.

Steps to Set Up Cntlm

To resolve these issues, I installed cntlm. Setting up cntlm is straightforward: simply locate the ini file at C:\Program Files\Cntlm\cntlm.ini.

  1. Open the C:\Program Files\Cntlm\cntlm.ini file (you may need admin rights).
  2. Locate the Username and Domain lines (probably lines 8-9).
    • Add your username.
    • Add your domain.
  3. In the command prompt, run:
cd C:\Program Files\Cntlm\
cntlm -M
cntlm -H  
  • 您将被要求输入密码:
 cygwin warning:
   MS-DOS style path detected: C:\Program Files\Cntlm\cntlm.ini
   Preferred POSIX equivalent is: /Cntlm/cntlm.ini
   CYGWIN environment variable option "nodosfilewarning" turns off this warning.
   Consult the user's guide for more details about POSIX paths:
     http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
 Password:
cntlm -H 命令的输出结果大致如下:
PassLM          561DF6AF15D5A5ADG  
PassNT          A1D651A5F15DFA5AD  
PassNTLMv2      A1D65F1A65D1ASD51  # Only for user 'user name', domain 'DOMAIN'
  • 建议使用PassNTLMv2,因此在PassLMPassNT之前添加#或不使用它们
  • cntlm -H的输出粘贴到ini文件中,替换PassLMPassNTPassNTMLv2的行,或注释原始行并添加您自己的行。
  • 添加您的代理服务器。如果您不知道代理服务器是什么……做我所做的事情,通过查找HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings中的AutoConfigURL注册表键来查找我的代理自动配置文件。转到该网址并查看代码,这恰好是JavaScript。
  • 可选地,您可以通过更改Listen ####行的端口(其中####是端口号)来更改cntlm侦听的端口。
  • 使用cntlm设置NPM

    因此,您将npm指向cntml代理,可以使用ip,我使用了localhost和cntlm的默认端口3128,因此我的代理url如下:

    http://localhost:3128

    用正确的命令:

    npm config set proxy http://localhost:3128

    就简单得多了。您可以使用相同的url设置所有工具,并只在一个位置更新密码。生活变得更加简单。

    必须设置npm CA证书

    来自npm文档ca

    如果您的公司代理正在拦截具有自己的自签名证书的https连接,则必须执行此操作,以避免禁用npm config set strict-ssl false(大忌)。

    基本步骤

    1. 从浏览器中获取证书(Chrome效果很好)。将其导出为Base-64编码X.509(.CER)
    2. 将新行替换为\n
    3. 编辑您的.npmrc添加一行ca[]="-----BEGIN CERTIFICATE-----\nXXXX\nXXXX\n-----END CERTIFICATE-----"

    问题

    我注意到有时npm会卡住,所以我停止(有时是强制性的)cntlm并重新启动它。


    1
    在Windows上,cntlm的替代方案是https://github.com/genotrance/px - Manuel Alves

    7

    对于在企业防火墙后面遇到问题的人,以及SSL(无法获取本地颁发者证书)的问题,这里有一些你可以尝试的步骤:

    忘记SSL

    如果你不关心SSL,那么你可以按照之前许多贡献者的建议设置代理并将注册表更改为非安全版本:

    npm config set proxy http://username:password@proxyname:port
    npm config set https-proxy http://username:password@proxyname:port
    npm config set registry http://registry.npmjs.org/
    

    这里有一个需要注意的问题,我的代理凭据在安全和非安全请求中是相同的(请注意我将协议保留为http:// 用于https-proxy配置)。可能对你也是一样的,也可能不是。

    我想保留SSL

    如果您希望保留SSL,而不想使用strict-ssl=false,则需要更多的工作。对于我来说,我在企业防火墙后面,我们正在使用自签名证书,因此我收到了错误unable to get local issuer certificate。如果您和我处于同样的情况,则需要在npm配置文件中设置cafile=选项。首先,您需要创建一个PEM文件,其中包含有关您的自签名证书的信息。如果您不知道如何做到这一点,以下是Windows环境的说明,而不使用第三方软件:

    我们需要明确指出应该信任哪些证书,因为我们使用自签名证书。对于我的示例,我使用Chrome导航到www.google.com,以便可以获取证书。

    在Chrome中,转到检查-> 安全 -> 查看证书。您将看到所有允许SSL连接的证书。请注意,这些证书都是自签名的。模糊的部分是我的公司,我们不是认证机构。您可以将完整的证书路径另存为P7B文件,也可以将证书分别导出为CER文件(Base64编码)。将完整路径导出为P7B对您没什么好处,因为您反过来还需要在证书管理器中打开此文件并导出为单独的CER文件。在Windows中,双击P7B文件将打开证书管理器应用程序。

    enter image description here

    将其导出为CER(Base 64)实际上是以下格式的文本文件:

    -----BEGIN CERTIFICATE-----
    MIIGqzCCBZOgAwIBAgITIwAAABWhFPjwukYhTAADAAAAFTANBgkqhkiG9w0BAQUF
    ADBFMRMwEQYKCZImiZPyLGQBGRYDY29tMRYwFAYKCZImiZPyLGQBGRYGaXJ2aW5n
    b0pvCkNmjWzaNNUg2hYET+pP5nP75aRu+kPRl9UnlQ....rest of certificate...
    -----END CERTIFICATE-----
    

    要创建PEM文件,我们只需要将这些证书叠放在一起形成一个单独的文件,并将扩展名更改为.pem。我使用记事本完成此操作。
    您需要按照证书路径的相反顺序堆叠证书。因此,在上面的例子中,我会从*.google.com开始,然后在其下方粘贴Websense,然后是Issuing CA 1等。这样,证书就会从上到下进行解析,寻找适当的根CA。仅包含根CA是不起作用的,但我们也不需要包含所有证书。从上面的路径中,我只需要包含在Websense证书之前的那些证书(Issuing CA 1、Policy CA、Root CA)。
    一旦将这些自签名证书保存到PEM文件中,我们就可以指示npm将这些证书用作我们信任的CA。只需设置配置文件即可。
    npm config set cafile "C:\yourcerts.pem"
    

    现在,您已经设置了代理(http和https),并将注册表设置为https://registry.npmjs.org,因此您应该能够在公司防火墙背后安装具有自签名证书的软件包,而无需取消 strict-ssl 设置。


    7

    如果NPM出现身份验证错误,您可以检查Fiddler。它很容易安装和配置。将Fiddler规则设置为自动身份验证。在.npmrc中设置以下属性:

    registry=http://registry.npmjs.org
    proxy=http://127.0.0.1:8888
    https-proxy=http://127.0.0.1:8888
    http-proxy=http://127.0.0.1:8888
    strict-ssl=false
    

    它对我有用 :)

    令人惊讶的是,我用于代理的所有配置都没有起作用,但当我使用这个和打开Fiddler时,它可以正常使用... - Roberto

    7
    我曾遇到过一些问题,最终我所做的是:
    1. Used Fiddler, with "Automatically Authenticate" selected
    2. In fiddler custom rules, i added

      if (m_AutoAuth) {oSession["X-AutoAuth"] = "domain\\username:password";}
      
    3. Finally in npm i set the proxy to http://localhost:8888

    这个很好用。


    谢谢!完美解决了!!我的情况: 用户名是“domain/username”格式。 密码中有一个“@”。根本不需要进行任何URL编码/解码等操作。 - A_B
    对我来说完美地工作了。非常感谢你。只是想指出,使用“domain\username:password”可能会带来身份盗窃的安全威胁。相反,在自定义规则中使用“(default)”配置效果很好。在使用“npm”时,Fiddler需要保持运行状态才能正常工作。 - pk10
    @pk10 你好,我想知道这个实际上是如何工作的? - Limyandi Vico Trico

    6

    您需要向服务器管理员或客服获取代理主机和端口。

    在此之后进行设置。

    npm config set http_proxy http://username:password@proxyofmycomp.com:itsport
    npm config set proxy http://username:password@proxyofmycomp.com:itsport
    

    如果密码中有特殊字符,请尝试使用%urlencode。例如:井号(#)应替换为%23。
    这对我起作用...

    5
    尝试这个,按以下方式在npm中设置代理。
    npm config set proxy "http://<user-name>:<password>@<proxy-url>:<port>"
    npm config set https-proxy "http://<user-name>:<password>@<proxy-url>:<port>"
    npm config set strict-ssl false
    npm config set registry "http://registry.npmjs.org/"
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接