How to set npm credentials using `npm login` without reading from stdin?
Solution 1
TL;DR: Make an HTTP request directly to the registry:
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
Rationale
Behind the scenes npm adduser
makes an HTTP request to the registry. Instead of forcing adduser
to behave the way you want, you could make the request directly to the registry without going through the cli and then set the auth token with npm set
.
The source code suggests that you could make a PUT request to http://your_registry/-/user/org.couchdb.user:your-username
with the following payload
{
name: username,
password: password
}
and that would create a new user in the registry.
Many thanks to @shawnzhu for having found a more cleaner approach to solve the problem.
Solution 2
npm set //<registry>/:_authToken $TOKEN
Example for Github Package Registry:
npm set //npm.pkg.github.com/:_authToken $GITHUB_TOKEN
This is the simplest solution that I have found.
Solution 3
npm-cli-login
allows you to log in to NPM without STDIN.
In order to install run:
npm install -g npm-cli-login
Example usage:
npm-cli-login -u Username -p Password -e [email protected] -r https://your-private-registry-link
Solution 4
I took a slightly different approach that seems to work great still. To begin with, you will need an auth token. This is easily obtainable by locally running npm adduser
and then grabbing the generated token from your ~/.npmrc
located in your user folder. In order to be authenticated on your ci server this auth token needs to be appended to the registry URL in the user's .npmrc
(similar to how it was locally), not the .npmrc
located in the repo, so these worked great as script steps in my CI configuration
- echo "//<npm-registry>:8080/:_authToken=$AUTH_TOKEN" > ~/.npmrc
- npm publish
where AUTH_TOKEN is stored as a secret variable in your settings.
A good way to test this is to replace npm publish
with npm whoami
to test and make sure it successfully logged you in.
Here is my entire publish configuration
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!'
I'm using gitlab-ci but I don't see why this wouldn't apply to any ci application.
Solution 5
An expect script worked for me. You need to make sure expect is installed, this command should do it for ubuntu:
apt-get install expect-dev
Your script could look something like this (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
}
And then call it like this:
expect -f npm_login_expect myuser mypassword "[email protected]"
Related videos on Youtube
![shawnzhu](https://i.stack.imgur.com/sR6j4.png?s=256&g=1)
Comments
-
shawnzhu over 2 years
I'm trying to automate
npm publish
inside a Docker container, but I receive an error when thenpm login
command tries to read the username and email:npm login << EOF username password email EOF
It works in a Bash terminal, but in a container (without
stdin
) it shows error:Username: Password: npm ERR! cb() never called! npm ERR! not ok code 0
According to npm-adduser:
The username, password, and email are read in from prompts.
How can I run
npm login
without usingstdin
?-
dokaspar over 7 yearsYour command actually worked for me, thanks! :) The only thing missing was to add the
--repository
parameter...
-
-
shawnzhu about 10 yearsThanks. the root cause is
npm adduser
always ask for input from stdin which I can't make. Then I found another way which is kind of trick to generate a working~/.npmrc
. see github.com/npm/npm-registry-client/blob/master/lib/… -
shawnzhu over 9 yearsYes if there is tty that
expect
can read. my problem is, there's no STDIN nor sudo tty at all. -
NikG over 9 yearsWorked a treat in a chef recipe as well.
-
Adam K Dean over 8 years@shawnzu it'd be nice if you'd post the solution for the rest of the internet, as the link you gave uses master instead of a sha, so it's out of date now :(
-
Marc-Andre R. over 7 yearsThis is clever but doesn't seems to work in my case. We're using ProGet and the output of that command see to only return and object like { "ok":"true" } and no tokens whatsoever. Seems like proget change the response from that command... I'll kept you posted if I found anything.
-
AntouanK over 7 yearsWhat if we just want to login, and not add a new user? I get bcak "user exists" with the above PUT request.
-
AntouanK over 7 yearsgot the solution : github.com/rlidwka/sinopia/issues/329#issuecomment-217406747
-
King Midas about 7 yearsIf you have already logged in with
npm login
, the information of the token can be found at file~/.npmrc
in your home folder. Then, with onlynpm set //your-registry.com/:_authToken="wKaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa="
-
Highriser almost 7 yearsHas anyone else the problem that this solution is not working? I always get "You don't have permission to publish .."
-
Lovey over 6 yearsNot working for me. I keep getting
Username: Password: npm ERR! cb() never called!
-
vedo27 almost 5 yearsFor some reason the regex did not work for me on the new Github registry. This one fixed it:
grep -oP "token\":\"\K\w+")
-
wdlax11 over 4 yearsthis doesnt work for me at all... i have it in my .npmrc file and try npm install still authentication error.
-
JRichardsz over 4 yearswhat is your nodejs version? Delete the old .npmrc and try again!
-
Chris Stryczynski over 4 yearsThis gives me an error of
user registration disabled
when using verdaccio... -
was_777 over 4 yearsI am getting error :
spawn npm login npm ERR! wrong # args: should be "eof channelId" while executing "eof" invoked from within "expect { timeout exit 1 eof }" (file "npm_login.sh" line 20)
-
Beto Frega about 4 yearsThis is the perfect solution
-
Ami Gulzadi almost 4 yearsWorked for me, to login to a Nexus private registry without any internet access.
-
ErikE over 3 years
npm ping
has been set up precisely to allow testing connectivity and credentials. Also note that sometimes it's useful to output to a local.npmrc
file instead of always putting it in the user's HOME folder—especially to avoid blowing up the user's normal day-to-day configuration just because some automation command was run. -
Kipras Melnikovas almost 3 yearsnote for github actions users: secrets are accessible via
${{ secrets.SECRET_NAME }}
, thus you'll need tonpm set "//registry.npmjs.org/:_authToken" ${{ secrets.NPM_TOKEN_OR_WHATEVER }}
-
Florian Wendelborn over 2 yearsnote for docker users: docker build may log the clear-text value of NPM_TOKEN to your console/ci logs. You can avoid this by putting this command into a
./npm-config.sh
and executing that instead.