How should I set _auth in .npmrc when using a Nexus https npm registry proxy?
Context
My
.npmrc
file seems to be correctly read (checked withnpm config ls -l
both from command line and from Maven build).the machine on which
npm
is run cannot connect directly to the net, it can only connect to a Nexus npm registry url. Therefore, proxy propertiesproxy
andhttps-proxy
are not set.As access to Nexus is restricted, I have generated an access token from within Nexus.
Nexus security tokens are made from a username and a password which both contain characters such as
/
which usually have to be "url encoded"as expected, with this configuration, when running
npm install
detects no proxy.Nexus npm registry proxy seems to be correctly set (I can both access
json
files and downloadtgz
files using a web browser after having connected using the token generated)If I set
registry
tohttp://registry.npmjs.org/
and comment_auth
,email
,always-auth
,strict-ssl
properties, and addproxy
andhttps-proxy
configuration,npm install
works as expected (but I won't be able to do it on target environment)
Content of .npmrc
file
; Nexus proxy registry pointing to http://registry.npmjs.org/
registry = https://<host>/nexus/content/repositories/npmjs-registry/
; base64 encoded authentication token
_auth = <see question below>
; required by Nexus
email = <valid email>
; force auth to be used for GET requests
always-auth = true
; we don't want to put certificates in .npmrc
strict-ssl = false
loglevel = silly
Question
How should I generate the _auth
property properly in order to have npm install
work as expected?
I tried so far
- base64Encode(
<username>:<password>
)- results in
npm info retry will retry, error on last attempt: Error: socket hang up
- results in
- base64Encode(urlencode(
<username>:<password>
))- results in
npm info retry will retry, error on last attempt: Error: This request requires auth credentials. Run `npm login` and repeat the request.
- results in
- base64Encode(urlencode(
<username>
):
urlencode(<password>
))- results in
npm info retry will retry, error on last attempt: Error: socket hang up
- results in
When getting the socket hang up
error I have the following stack trace:
http request GET https://<host>/nexus/content/repositories/npmjs-registry/fsevents
sill fetchPackageMetaData Error: socket hang up
sill fetchPackageMetaData at TLSSocket.onHangUp (_tls_wrap.js:1035:19)
sill fetchPackageMetaData at TLSSocket.g (events.js:260:16)
sill fetchPackageMetaData at emitNone (events.js:72:20)
sill fetchPackageMetaData at TLSSocket.emit (events.js:166:7)
sill fetchPackageMetaData at endReadableNT (_stream_readable.js:905:12)
sill fetchPackageMetaData at doNTCallback2 (node.js:441:9)
sill fetchPackageMetaData at process._tickCallback (node.js:355:17)
sill fetchPackageMetaData error for fsevents@^1.0.0 { [Error: socket hang up] code: 'ECONNRESET' }
WARN install Couldn't install optional dependency: socket hang up
verb install Error: socket hang up
verb install at TLSSocket.onHangUp (_tls_wrap.js:1035:19)
verb install at TLSSocket.g (events.js:260:16)
verb install at emitNone (events.js:72:20)
verb install at TLSSocket.emit (events.js:166:7)
verb install at endReadableNT (_stream_readable.js:905:12)
verb install at doNTCallback2 (node.js:441:9)
verb install at process._tickCallback (node.js:355:17)
When getting the This request requires auth credentials
error I have the following stack trace:
npm sill fetchPackageMetaData Error: This request requires auth credentials. Run `npm login` and repeat the request.
npm sill fetchPackageMetaData at CachingRegistryClient.authify (<root>\ui\target\node\node_modules\npm\node_modules\npm-registry-client\lib\authify.js:17:14)
npm sill fetchPackageMetaData at CachingRegistryClient.makeRequest (<root>\ui\target\node\node_modules\npm\node_modules\npm-registry-client\lib\request.js:103:17)
npm sill fetchPackageMetaData at <root>\ui\target\node\node_modules\npm\node_modules\npm-registry-client\lib\request.js:66:17
npm sill fetchPackageMetaData at RetryOperation._fn (<root>\ui\target\node\node_modules\npm\node_modules\npm-registry-client\lib\attempt.js:18:5)
npm sill fetchPackageMetaData at null._onTimeout (<root>\ui\target\node\node_modules\npm\node_modules\retry\lib\retry_operation.js:49:10)
npm sill fetchPackageMetaData at Timer.listOnTimeout (timers.js:92:15)
npm sill fetchPackageMetaData error for fsevents@^1.0.0 [Error: This request requires auth credentials. Run `npm login` and repeat the request.]
npm WARN install Couldn't install optional dependency: This request requires auth credentials. Run `npm login` and repeat the request.
npm verb install Error: This request requires auth credentials. Run `npm login` and repeat the request.
npm verb install at CachingRegistryClient.authify (<root>\ui\target\node\node_modules\npm\node_modules\npm-registry-client\lib\authify.js:17:14)
npm verb install at CachingRegistryClient.makeRequest (<root>\ui\target\node\node_modules\npm\node_modules\npm-registry-client\lib\request.js:103:17)
npm verb install at <root>\ui\target\node\node_modules\npm\node_modules\npm-registry-client\lib\request.js:66:17
npm verb install at RetryOperation._fn (<root>\ui\target\node\node_modules\npm\node_modules\npm-registry-client\lib\attempt.js:18:5)
npm verb install at null._onTimeout (<root>\ui\target\node\node_modules\npm\node_modules\retry\lib\retry_operation.js:49:10)
npm verb install at Timer.listOnTimeout (timers.js:92:15)
Thanks in advance.
Solution 1:
https://books.sonatype.com/nexus-book/reference/npm-deploying-packages.html
$ echo -n 'username:password' | openssl base64
Solution 2:
If you have authorization token you should not use username:password. I suggest you:
-
Generate token
- Delete your ~/.npmrc or rename it.
- Make sure your env settings like $NPM_CONFIG_* are unset.
- Verify that email and other settings are unset by using:
npm config list
- Log into the npm using:
npm login --registry=https://nexus.whatever.registry/respository/npm-whatever-group/
- Once you are logged - you are logged. The npm should generate a token for it in your ~/.npmrc. It will look like:
//nexus.whatever.registry/respository/npm-whatever-group/:_authToken=NpmToken.YOUR-LOVELY-TOKEN-IN-HEX
- You can use that token in your project, CI pipeline, and other ones. Make sure in your project .npmrc there is:
//nexus.whatever.registry/respository/npm-whatever-group/:_authToken=NpmToken.YOUR-LOVELY-TOKEN-IN-HEX
email = <EMAIL_USED_FOR_TOKEN_GENERATION>
always-auth = true
registry = https://nexus.whatever.registry/respository/npm-whatever-group/
-
If you have problems with authentication/certs:
- add env variable (also to your CI/CD pipline) $NODE_EXTRA_CA_CERTS to point to /home/wherever/is/your/cert.pem
-
For CI/CD pipelines (like gitlabs or jenikins):
- consider replacing actual values from your .npmrc project file with
${RELEVANT_ENV_VARIABLES}
. This way you will make them less visible and always self-updating on change of pipline.
- consider replacing actual values from your .npmrc project file with
Hope this help.
Solution 3:
After having looked at registry-client
code I found the answer, here it is. I post it as it may help other people:
base64Encode(<username>:<password>)
By the way, there is an URL encoding, but it's authify.js
that takes care of it.
The "socket hang up" problem I'm facing is due to the fact that if a proxy is set in Windows configuration, when launching npm
from CLI (and not from a Maven build) all ```.npmrc`` proxy settings seem to be ignored while native proxy exclusions (for corporate urls) are ignored by npm. I'll open a ticket to report this weird behavior.
Solution 4:
Before you run npm login, please follow the instructions below :
1) Create an ~/.npmrc file with the following contents:
registry=https://example.com/repository/npm-group/
[email protected]
always-auth=true
//example.com/repository/npm-group/:_authToken=
2) run `npm login`
# npm login
Username: firstname.lastname
Password:
Email: (this IS public) [email protected]
Logged in as firstname,lastname on https://example.com/repository/npm-group/.
Use the same password you use to login to example.com
Solution 5:
I don't know about Nexus, but we use artifactory as an npm repo, and there I can create my auth token by calling base64encode(username:encryptedPassword)
with encryptedPassword
being the one I get from my personal artifactory profile.
Maybe this helps.