无论如何在没有从STDIN读取输入的情况下通过`npm login`设置npm凭证?

sha*_*zhu 38 bash node.js npm docker

我正在尝试npm publish在docker容器内自动化,但是当npm login命令尝试从提示中读取用户名和电子邮件时遇到了麻烦:

npm login << EOF
username
password
email
EOF
Run Code Online (Sandbox Code Playgroud)

它在终端bash中工作,但在没有打开STDIN的情况下不在容器中,并显示以下错误消息:

Username: Password: npm ERR! cb() never called!
npm ERR! not ok code 0
Run Code Online (Sandbox Code Playgroud)

根据npm-adduser:

用户名,密码和电子邮件将从提示中读入.

那么如何在npm login没有STDIN打开的情况下运行?

dan*_*cic 32

TL; DR:直接向注册表发出HTTP请求:

TOKEN=$(curl -s \
  -H "Accept: application/json" \
  -H "Content-Type:application/json" \
  -X PUT --data '{"name": "username_here", "password": "password_here"}' \
  http://your_registry/-/user/org.couchdb.user:username_here 2>&1 | grep -Po \
  '(?<="token": ")[^"]*')

npm set registry "http://your_registry"
npm set //your_registry/:_authToken $TOKEN
Run Code Online (Sandbox Code Playgroud)

合理

在后台npm adduser向注册表发出HTTP请求.adduser您可以直接向注册表发出请求,而无需通过cli,然后设置auth令牌,而不是强制按照您想要的方式运行npm set.

源代码建议您可以http://your_registry/-/user/org.couchdb.user:your-username使用以下有效内容发出PUT请求

{
  name: username,
  password: password
}
Run Code Online (Sandbox Code Playgroud)

这将在注册表中创建一个新用户.

非常感谢@shawnzhu找到了更清洁的方法来解决问题.

  • 如果我们只想登录而不添加新用户怎么办?我通过上述 PUT 请求得到 bcak“用户存在”。 (2认同)
  • 得到了解决方案:https://github.com/rlidwka/sinopia/issues/329#issuecomment-217406747 (2认同)
  • 如果您已经使用“ npm login”登录,则可以在主文件夹中的文件〜/ .npmrc中找到令牌的信息。然后,仅设置`npm // //your-registry.com /:_ authToken =“ wKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =”` (2认同)
  • 还有其他人遇到此解决方案不起作用的问题吗?我总是收到“您无权发布..” (2认同)

Žel*_*vić 27

npm set //<registry>/:_authToken $TOKEN
Run Code Online (Sandbox Code Playgroud)

Github 包注册表示例:

npm set //npm.pkg.github.com/:_authToken $GITHUB_TOKEN
Run Code Online (Sandbox Code Playgroud)

这是我找到的最简单的解决方案。

  • 这是完美的解决方案 (3认同)

JRi*_*dsz 16

这在我的一个 DevOps 流程中有效

脚步

  1. 为了安全起见,使用 shell 使用基于 64 的 npm 注册表凭据生成_auth :
    echo -n 'myuser:mypassword' | openssl base64
    Result will be something like : eWFob29vb2E=
Run Code Online (Sandbox Code Playgroud)
  1. 在 npm install之前设置 npm 注册表 url 和 _auth ...
    npm config set registry https://nexus-acme.com/repository/npm-group/
    npm config set _auth eWFob29vb2E=
Run Code Online (Sandbox Code Playgroud)

就这样。您可以运行npm install,您的私有模块将被下载。

笔记

  • Nodejs 提供基本身份验证(用户:密码)作为有效选项:
  • 对于基本身份验证,基本令牌通常存储在~/.npmrc
  • 这个基本令牌使用 base64 进行编码,因此任何有权访问您的计算机的人都可以轻松解码并查看您的用户名:密码。如果您担心,请询问 Nodejs 创建者为什么要使用它。
  • 对于开发人员和 DevOps 流程,通常采用此策略:maven (java)、pip (python)、nuget(c#) 等
  • 如果您关心在开发人员计算机中存储秘密,您应该使用一些高级 npm 包注册表,例如 github,其中提供了令牌(带有过期时间)。无论如何,这个令牌应该存储在机器中,因此如果不登录和/或不存储获得的令牌,就无法稳定与 NPM 注册表的连接
  • 一个疯狂的选择可能是 oauth2,在每个 npm 安装上都需要 Web 登录。我无法想象 devops 自动化(纯 shell),其中每次 npm 安装时,人类系统管理员都需要执行 Web 登录......
  • 对于非交互式流程,服务器或开发人员计算机中始终需要机密。


Ted*_*ott 9

期望脚本对我有用.你需要确保安装了expect,这个命令应该为ubuntu做:

apt-get install expect-dev
Run Code Online (Sandbox Code Playgroud)

你的脚本看起来像这样(npm_login_expect):

#!/usr/bin/expect -f

# set our args into variables
set i 0; foreach n $argv {set "p[incr i]" $n}

set timeout 60
#npm login command, add whatever command-line args are necessary
spawn npm login
match_max 100000

expect "Username"    
send "$p1\r"

expect "Password"
send "$p2\r" 

expect "Email"
send "$p3\r"

expect {
   timeout      exit 1
   eof
}
Run Code Online (Sandbox Code Playgroud)

然后像这样调用它:

expect -f npm_login_expect myuser mypassword "myuser@domain.com"
Run Code Online (Sandbox Code Playgroud)


小智 8

我采取了一种略微不同的方法,似乎仍然很好用.首先,您需要一个身份验证令牌.这可以通过本地运行npm adduser,然后从您~/.npmrc的用户文件夹中找到生成的令牌轻松获得.为了在您的ci服务器上进行身份验证,此身份验证令牌需要附加到用户的注册表URL .npmrc(类似于本地的注册表URL ),而不是.npmrc位于repo中的位置,因此这些在我的CI配置中作为脚本步骤工作得很好

- echo "//<npm-registry>:8080/:_authToken=$AUTH_TOKEN" > ~/.npmrc
- npm publish
Run Code Online (Sandbox Code Playgroud)

其中AUTH_TOKEN在您的设置中存储为秘密变量.测试一个很好的办法是更换npm publishnpm whoami测试,并确保它成功登录你进来.

这是我的整个发布配置

publish:
  stage: deploy
  only:
    - tags
  script:
    - yarn run build
    - echo "//<npm-registry>:8080/:_authToken=$NPME_AUTH_TOKEN" > ~/.npmrc
    - npm publish
    - echo 'Congrats on your publication!'
Run Code Online (Sandbox Code Playgroud)

我正在使用gitlab-ci,但我不明白为什么这不适用于任何ci应用程序.


dre*_*res 8

一种解决方案是获取令牌并更新 ~/.npmrc

export ARTIFACTORY_TOKEN=`curl --silent --show-error --fail -u $ARTIFACTORY_USERNAME:$ARTIFACTORY_API_KEY https://artifactory.my.io/artifactory/api/npm/auth | \
grep -oP '_auth[\s?]=[\s?]\K(.*)$'`

echo "@my:registry=https://artifactory.my.io/artifactory/api/npm/npm-release-local/" > ~/.npmrc
echo "//artifactory.my.io/artifactory/api/npm/npm-release-local/:_auth=${ARTIFACTORY_TOKEN}" >> ~/.npmrc
echo "//artifactory.my.io/artifactory/api/npm/npm-release-local/:email=${ARTIFACTORY_USERNAME}" >> ~/.npmrc
echo "//artifactory.my.io/artifactory/api/npm/npm-release-local/:always-auth=true" >> ~/.npmrc
Run Code Online (Sandbox Code Playgroud)

这可以防止从 npmjs 检索 @scope 包时出现问题


小智 6

npm-cli-login允许您在没有STDIN的情况下登录NPM。

为了安装运行

npm install -g npm-cli-login

用法示例:-

npm-cli-login -u用户名-p密码-e test@example.com -r https://您的私有注册中心链接


use*_*934 6

npm login命令将所有凭据存储在全局.npmrc文件中。模式并不相似,而且会发生变化。解释如下:

有两种模式,任何一种都可以。注意:npm 可能有其他模式存储身份验证数据,因此最好.npmrc在全局上下文中交叉检查文件的内容。

每次我们执行一个条目时,如果它不存在,npm login就会创建一个条目。.npmrc

所以这两个模式(我从 .npmrc 复制了以下几行)

//your_registry/:_authToken=amvasdfjkhjkjsdhflakjsdfhalskjh== //your_registry/:_authToken=NpmToken.6ca7867aba-d66a-32c0-9srr-fba908987d7987f

因此,唯一要做的就是从全局复制该行.npmrc并将其放入本地或项目中.npmrc,然后从 CI 运行npm publish命令。npm login不需要明确。


msc*_*dex 0

您可以使用 Expect 脚本,或者编写使用pty.js 的节点脚本。

  • @shawnzu,如果您将解决方案发布到互联网的其余部分,那就太好了,因为您提供的链接使用 master 而不是 sha,所以它现在已经过时了:( (7认同)