58

I am running Nexus 3.0.1-01, and am using it to host both Maven repositories and NPM registries. For NPM, I have a local mirror of npmjs.org, a local NPM registry and a group that combines the two...

enter image description here

I have been using this with npm internally, where I can use the npm-public group as my registry and this has been working fine. So, I can use Nexus to mirror npmjs.

The next step is to take locally written npm modules and publish them to npm-releases (on my Nexus instance) so that these modules can be shared amongst the delivery teams here. I've been able to build out a package, and npm pack seems to behave.

I have run npm adduser to provide my Nexus credentials to my npm environment. I am using the same username/password I use when I log into the Nexus web app, and my user is assigned the admin role (so I should have all permissions). I can see the credentials in my .npmrc file

enter image description here

My registry value is still the npm-public group which combined the mirror and my local registry. I have ensured that the package.json of the module I am attempting to deploy has a "publishConfig" section that points to the url of the local registry (not the public group)

enter image description here

However, despite all of that, calling "npm publish" results in a 401 error...

enter image description here

Looking at the npm-debug.log, I can see it's attempting to call the HTTP PUT call to push the assembled tgz file to the registry, and this is returning a 401 error

enter image description here

I have enabled debug logging on the shiro package in the server, but I only ever see a single message thinking it needs authentication

2016-09-13 08:56:28,590+1000 DEBUG [qtp1257823896-4030] *UNKNOWN org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter - Authentication required: sending 401 Authentication challenge response.

According to the documentation, I've done all I'm supposed to do (npm add user) but I am unable to successfully deploy an npm module to my local repository.

Are there additional options I need to use when calling npm publish? Are there additional settings I need to make to the hosted npm repository in my server that will allow me to publish to it? I pretty much created it using the default values. Have I missed a step that is preventing me from deploying to my hosted npm registry?

Any help would be greatly appreciated, as I am stuck at the moment.

EdH
  • 4,918
  • 4
  • 24
  • 34

5 Answers5

118

As it turns out, I did not have the Npm Bearer Token Realm in my list of active realms. Once I moved it to Active, the publish completed successfully!

enter image description here

EdH
  • 4,918
  • 4
  • 24
  • 34
  • Had 401 error on publish recently. Confirmation: solution working with most recent versions: Nexus OSS 3.9.0-01 and Node.js 9.8.0. But if nginx reverse proxy being used: authentication can be broken by nginx.config misconfiguration. Check https://books.sonatype.com/nexus-book/3.0/reference/install.html#reverse-proxy for more details – aillusions Mar 13 '18 at 11:20
  • 6
    As summary to the solution: enable Npm Bearer Token Realm and `"publishConfig": { "registry": "https://your-nexus-host/nexus/repository/npm-private/" } npm config set registry https://your-nexus-host/nexus/repository/npm-group/ npm adduser --registry=https://your-nexus-host/nexus/repository/npm-private/ ( provide nexux-user-name, nexux-user-password, nexux-user-email) npm publish .` – aillusions Mar 13 '18 at 11:25
  • 1
    This solution also helped me get NuGet push working (just had to add Nuget API-Key Realm) – Josh Apr 20 '18 at 16:55
16

Additonally to @EdH's answer we discovered that the format of .npmrc has changed so base64 encoded _auth will not work anymore... and the token has to be created by logging into the repo.

old .npmrc

registry=https://host/repo
_auth=12afdjsljl123213

new .npmrc

//host/repo/:_authtoken=uuidOfToken
  • 2
    Notice: When you've logged via `npm login`, npm will add an entry into your *global* `~/.npmrc` file. There you find the base64 encoded token you can copy into your local .npmrc or generate it in your CI pipeline. – Patrick Hillert May 29 '18 at 15:13
9

Additionally to @Daniel's answer, I discovered that when adding user credentials/logging into npm, you can't have a trailing slash on the registry url.

Bad:

npm adduser --registry=https://repo.localhost/repository/npm-internal/

Good:

npm adduser --registry=https://repo/repository/npm-internal

Also, if you're looking to automate the login (i.e. non-interactively), I used a good tool called npm-cli-login.

npm-cli-login -u admin -p admin123 -e nick@foo.bar -r https://repo/repository/npm-internal
Nick Grealy
  • 24,216
  • 9
  • 104
  • 119
  • 2
    Note that in recent versions of npm, in order to login to Nexus with Basic Auth, you'll need to add the "--auth-type-legacy" argument to the "npm adduser" command. – Daniel Bower Jun 06 '18 at 03:07
  • 1
    this is actually incorrect as removing the trailing slash from the registry will cause npm to ignore the last path segment(bug?) – raven Apr 02 '20 at 14:22
3

I realize that this post is a couple years old now, but as of struggling with this issue for many hours, I finally found what worked for me that I've not seen in many other places. The problem was that I was not specifying the _authToken within the .npmrc file. Adding this as shown below resolved the issue and I was able to successfully run npm commands without a 401 error.

.npmrc

registry=https://test.repo.com/repository/npm-group/
//test.repo.com/repository/npm-group/:_authToken=NpmToken.${NPM_TOKEN}
0

Another reason why you might get such an error is that you might have enabled anonymous access to the server for the 'npm Bearer Token Realm'. After disabling anonymous access you must also remove .npmrc and re-add the registry and adduser.

raven
  • 775
  • 6
  • 22