How should I set _auth in .npmrc when using a Nexus https npm registry proxy?
NpmNexusNpm InstallNpm Problem Overview
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.
Npm Solutions
Solution 1 - Npm
https://books.sonatype.com/nexus-book/reference/npm-deploying-packages.html
$ echo -n 'username:password' | openssl base64
Solution 2 - Npm
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.
Hope this help.
Solution 3 - Npm
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 - Npm
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 - Npm
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.
Solution 6 - Npm
I just wrote a wrapper that stores the credentials in your systems keychain and provides them on the fly. Check out: https://github.com/Xiphe/npm_keychain_auth