Salta al contenuto principale

Plugin d'Autenticazione

Cos'è un Plugin d'Autenticazione?

È un tipo di plugin che consente di gestire chi accede o pubblica in un pacchetto specifico. Di default la htpasswd è integrata, ma è facilmente sostituibile dalla tua.

Per Iniziare

I plugin d'autenticazione sono definiti nella sezione auth:, come segue:

auth:
htpasswd:
file: ./htpasswd

anche più plugin sono incatenabili:

auth:
htpasswd:
file: ./htpasswd
anotherAuth:
foo: bar
bar: foo
lastPlugin:
foo: bar
bar: foo

Se uno dei plugin nella catena può risolvere la richiesta, i prossimi saranno ignorati.

Come funziona il plugin d'autenticazione?

Fondamentalmente dobbiamo restituire un oggetto con un solo metodo chiamato authenticate che riceverà 3 argomenti (user, password, callback).

A ogni richiesta, authenticate sarà innescato e il plugin dovrebbe restituire le credenziali, se authenticate fallisce, farà fallback al ruolo $anonymous di default.

API

  interface IPluginAuth<T> extends IPlugin<T> {
authenticate(user: string, password: string, cb: AuthCallback): void;
adduser?(user: string, password: string, cb: AuthCallback): void;
changePassword?(user: string, password: string, newPassword: string, cb: AuthCallback): void;
allow_publish?(user: RemoteUser, pkg: AllowAccess & PackageAccess, cb: AuthAccessCallback): void;
allow_access?(user: RemoteUser, pkg: AllowAccess & PackageAccess, cb: AuthAccessCallback): void;
allow_unpublish?(user: RemoteUser, pkg: AllowAccess & PackageAccess, cb: AuthAccessCallback): void;
apiJWTmiddleware?(helpers: any): Function;
}

Solo adduser, allow_access, apiJWTmiddleware, allow_publish e allow_unpublish sono facoltativi, Verdaccio fornisce un fallback in tutti questi casi.

Metodo apiJWTmiddleware

Dalla v4.0.0

apiJWTmiddleware è stato introdotto alla PR#1227 per avere il pieno controllo del gestore del token, sovrascrivere questo metodo disabiliterà il supporto a login/adduser. Consigliamo di non implementare questo metodo a meno che non sia totalmente necessario. Vedi un esempio completo qui.

Cosa dovrei restituire in ognuno dei metodi?

Verdaccio si basa sulle funzioni di callback al momento di scrittura di questa documentazione. Ogni metodo dovrebbe chiamare il metodo e ciò che restituisci è importante, revisioniamo come farlo.

Callback di authentication

Una volta eseguita l'autenticazione ci sono 2 opzioni per dare una risposta a verdaccio.

Se l'autenticazione fallisce

Se l'autenticazione è fallita, restituisci false come il secondo argomento.

callback(null, false)
Se l'autenticazione riesce

L'autenticazione è riuscita.

groups è un insieme di stringhe di cui l'utente fa parte.

 callback(null, groups);
Se l'autenticazione produce un errore

Il servizio d'autenticazione potrebbe fallire e potrebbe volerlo riflettere nella risposta dell'utente, es.: il servizio non è disponibile.

 import { getInternalError } from '@verdaccio/commons-api';

callback(getInternalError('something bad message), null);

Un fallimento nell'accesso non equivale all'errore del servizio, se vuoi notificare l'utente del fatto che le credenziali sono errate, basta restituire false invece di stringhe di gruppi. Il comportamento dipende prevalentemente da te.

Callback di adduser

Se adduser riesce

Se il servizio riesce a creare un utente, restituisci true come il secondo argomento.

callback(null, true)
Se adduser fallisce

Ogni altra azione differente dal successo deve restituire un errore.

import { getConflict } from '@verdaccio/commons-api';

const err = getConflict('maximum amount of users reached');

callback(err);

Callback di changePassword

Se la richiesta riesce

Se il servizio riesce a creare un utente, restituisci true come il secondo argomento.

const user = serviceUpdatePassword(user, password, newPassword);

callback(null, user)
Se la richiesta fallisce

Ogni altra azione differente dal successo deve restituire un errore.

import { getNotFound } from '@verdaccio/commons-api';

const err = getNotFound('user not found');

callback(err);

Callback di allow_access, allow_publish, o allow_unpublish

Questi metodi mirano a consentire o negare l'innesco di certe azioni.

Se la richiesta riesce

Se il servizio riesce a creare un utente, restituisci un true come il secondo argomento.


allow_access(user: RemoteUser, pkg: PackageAccess, cb: Callback): void {
const isAllowed: boolean = checkAction(user, pkg);

callback(null, isAllowed)
}
Se la richiesta fallisce

Ogni altra azione differente dal successo deve restituire un errore.

import { getNotFound } from '@verdaccio/commons-api';

const err = getForbidden('not allowed to access package');

callback(err);

Generare un plugin d'autenticazione

Per le informazioni dettagliate, controlla la pagina del nostro generatore di plugin. Esegui il comando yo nel tuo terminale e segui i passaggi.

➜ yo verdaccio-plugin

Appena trovato un `.yo-rc.json` in una cartella madre.
Impostando il root del progetto a: /Users/user/verdaccio_yo_generator

_-----_ ╭──────────────────────────╮
| | │ Benvenuto al generatore│
|--(o)--| │ generator-verdaccio-plug │
`---------´ │ di plugin! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
__'.___.'__
´ ` |° ´ Y `

? Qual è il nome del tuo plugin? service-name
? Seleziona la Lingua
typescript
? Che tipo di plugin vuoi creare? auth
? Sei pregato di descrivere il fantastico plugin d'autenticazione del tuo plugin
? Nome utente o dell'organizzazione di GitHub myusername
? Nome dell'Autore Mario Rossi
? Email dell'Autore mariorossi@gmail.com
? Accorda le tue parole chiave (virgola per dividere) verdaccio,plugin,autenticazione,fantastico,verdaccio-plugin
create verdaccio-plugin-authservice-name/package.json
create verdaccio-plugin-authservice-name/.gitignore
create verdaccio-plugin-authservice-name/.npmignore
create verdaccio-plugin-authservice-name/jest.config.js
create verdaccio-plugin-authservice-name/.babelrc
create verdaccio-plugin-authservice-name/.travis.yml
create verdaccio-plugin-authservice-name/README.md
create verdaccio-plugin-authservice-name/.eslintrc
create verdaccio-plugin-authservice-name/.eslintignore
create verdaccio-plugin-authservice-name/src/index.ts
create verdaccio-plugin-authservice-name/index.ts
create verdaccio-plugin-authservice-name/tsconfig.json
create verdaccio-plugin-authservice-name/types/index.ts
create verdaccio-plugin-authservice-name/.editorconfig

Ho fatto tutto. Eseguendo l'installazione di npm per farti installare le dipendenze necessarie. Se questo fallisce, prova a eseguire tu stesso il comando.


⸨ ░░░░░░░░░░░░░░░░░⸩ ⠋ fetchMetadata: sill pacote range manifest for @babel/plugin-syntax-jsx@^7.7.4 fetc

Dopo il termine dell'installazione, accedi all'impalcatura del tuo progetto.

➜ cd verdaccio-plugin-service-name
➜ cat package.json

{
"nome": "verdaccio-plugin-service-name",
"versione": "0.0.1",
"descrizione": "awesome auth plugin",
...

Esempio di implementazione completa di ES5

function Auth(config, stuff) {
var self = Object.create(Auth.prototype);
self._users = {};

// configurazione per questo modulo
self._config = config;

// registratore di verdaccio
self._logger = stuff.logger;

// passa il registratore di verdaccio a Idapauth
self._config.client_options.log = stuff.logger;

return self;
}

Auth.prototype.authenticate = function (user, password, callback) {
var LdapClient = new LdapAuth(self._config.client_options);
....
LdapClient.authenticate(user, password, function (err, ldapUser) {
...
var groups;
...
callback(null, groups);
});
};

module.exports = Auth;

E la configurazione somiglierà a questa:

auth:
htpasswd:
file: ./htpasswd

Dove htpasswd è il suffisso del nome del plugin. es: verdaccio-htpasswd e il resto del corpo sarebbero i parametri di configurazione del plugin.

Elenco di Plugin d'Autenticazione della Community

Hai sviluppato un nuovo plugin? Aggiungilo qui!