Si utilitzes el transport SSH per connectar-te a repositoris remots, és possible que tinguis una clau sense frase de pas, la qual cosa et permet transferir dades de manera segura sense haver de escriure el teu nom d’usuari i contrasenya. No obstant això, això no és possible amb els protocols HTTP: cada connexió necessita un nom d’usuari i una contrasenya. Això es complica encara més per als sistemes amb autenticació de dos factors, on el token que utilitzes com a contrasenya es genera aleatòriament i no es pot pronunciar.
Afortunadament, Git té un sistema de credencials que pot ajudar amb això. Git ofereix diverses opcions incloses:
-
Per defecte, no es guarda res en memòria cau. Cada connexió et demanarà el teu nom d’usuari i contrasenya.
-
El mode “cache” manté les credencials en memòria durant un cert període de temps. Cap de les contrasenyes es guarda mai al disc, i es purguen de la memòria cau després de 15 minuts.
-
El mode “store” guarda les credencials en un fitxer de text pla al disc, i no expiren mai. Això significa que fins que no canvies la teva contrasenya per a l’amfitrió de Git, no hauras de tornar a escriure les teves credencials. L’inconvenient d’aquest enfocament és que les teves contrasenyes es guarden en text clar en un fitxer pla al teu directori personal.
-
Si utilitzes macOS, Git ve amb un mode “osxkeychain”, que guarda les credencials en el llaç de claus segur que està vinculat al teu compte de sistema. Aquest mètode guarda les credencials al disc, i no expiren mai, però estan xifrades amb el mateix sistema que guarda els certificats HTTPS i les dades d’ompliment automàtic de Safari.
-
Si utilitzes Windows, pots habilitar la funció Git Credential Manager quan instal·les Git for Windows o instal·lar el últim GCM com a servei independent. Això és similar a l’ajudant “osxkeychain” descrit anteriorment, però utilitza l’Emmagatzematge de Credencials de Windows per controlar la informació sensible. També pot servir credencials a WSL1 o WSL2. Consulta Instruccions d’Instal·lació de GCM per a més informació.
Pots triar un d’aquests mètodes configurant un valor de configuració de Git:
$ git config --global credential.helper cacheAlguns d’aquests ajudants tenen opcions. L’ajudant “store” pot prendre un argument --file <path>, que personalitza on es guarda el fitxer de text pla (el valor per defecte és ~/.git-credentials). L’ajudant “cache” accepta l’opció --timeout <seconds>, que canvia la quantitat de temps que es manté en execució el seu dimoni (el valor per defecte és “900”, o 15 minuts). Aquí tens un exemple de com configurar l’ajudant “store” amb un nom de fitxer personalitzat:
$ git config --global credential.helper 'store --file ~/.my-credentials'Git fins i tot et permet configurar diversos ajudants. Quan busca credencials per a un amfitrió particular, Git els consultarà en ordre, i s’aturarà després de la primera resposta proporcionada. Quan guarda credencials, Git enviarà el nom d’usuari i la contrasenya a tots els ajudants de la llista, i ells poden triar què fer amb elles. Aquí tens un exemple de com es veuria un .gitconfig si tinguessis un fitxer de credencials en una unitat USB, però volguessis utilitzar la memòria cau en memòria per estalviar-te alguna cosa d’escriptura si la unitat no està connectada:
[credential]
helper = store --file /mnt/thumbdrive/.git-credentials
helper = cache --timeout 30000Com funciona tot això? La comanda arrel de Git per al sistema d’ajudants de credencials és git credential, que pren una comanda com a argument i després més entrada a través de stdin.
Això pot ser més fàcil d’entendre amb un exemple. Diguem que s’ha configurat un ajudant de credencials, i l’ajudant ha emmagatzemat credencials per a mygithost. Aquí tens una sessió que utilitza la comanda “fill”, que s’invoca quan Git intenta trobar credencials per a un amfitrió:
$ git credential fill (1)
protocol=https (2)
host=mygithost
(3)
protocol=https (4)
host=mygithost
username=bob
password=s3cre7
$ git credential fill (5)
protocol=https
host=unknownhost
Username for 'https://unknownhost': bob
Password for 'https://bob@unknownhost':
protocol=https
host=unknownhost
username=bob
password=s3cre7-
Aquesta és la línia de comandes que inicia la interacció.
-
Git-credential està esperant entrada a stdin. Li proporcionem les coses que sabem: el protocol i el nom d’amfitrió.
-
Una línia en blanc indica que l’entrada està completa, i el sistema de credencials hauria de respondre amb el que sap.
-
Git-credential pren el control, i escriu a stdout amb els fragments d’informació que ha trobat.
-
Si no es troben credencials, Git demana a l’usuari el nom d’usuari i la contrasenya, i els proporciona de nou a l’invocació de stdout (aquí estan adjunts a la mateixa consola).
El sistema de credencials està invocant realment un programa que és separat de Git mateix; quin i com depèn del valor de configuració credential.helper. Hi ha diverses formes que pot prendre:
Valor de configuració |
Comportament |
|
Executa |
|
Executa |
|
Executa |
|
Codi després de |
Així que els ajudants esmentats anteriorment en realitat es diuen git-credential-cache, git-credential-store, i així successivament, i podem configurar-los per prendre arguments de línia de comandes. La forma general per a això és “git-credential-foo [args] <action>”. El protocol stdin/stdout és el mateix que git-credential, però utilitzen un conjunt lleugerament diferent d’accions:
-
getés una sol·licitud per a un parell nom d’usuari/contrasenya. -
storeés una sol·licitud per guardar un conjunt de credencials a la memòria d’aquest ajudant. -
erasepurga les credencials per a les propietats donades de la memòria d’aquest ajudant.
Per a les accions store i erase, no es requereix cap resposta (Git l’ignora de totes maneres). Per a l’acció get, però, Git està molt interessat en el que l’ajudant té a dir. Si l’ajudant no sap res útil, simplement pot sortir sense cap sortida, però si sap alguna cosa, hauria d’augmentar la informació proporcionada amb la informació que ha emmagatzemat. La sortida es tracta com una sèrie d’instruccions d’assignació; qualsevol cosa proporcionada reemplaçarà el que Git ja sap.
Aquí tens el mateix exemple d’abans, però saltant git-credential i anant directament a git-credential-store:
$ git credential-store --file ~/git.store store (1)
protocol=https
host=mygithost
username=bob
password=s3cre7
$ git credential-store --file ~/git.store get (2)
protocol=https
host=mygithost
username=bob (3)
password=s3cre7-
Aquí li diem a
git-credential-storeque guardi algunes credencials: el nom d’usuari “bob” i la contrasenya “s3cre7” s’han d’utilitzar quan s’accedeix ahttps://mygithost. -
Ara recuperarem aquestes credencials. Proporcionem les parts de la connexió que ja coneixem (
https://mygithost), i una línia en blanc. -
git-credential-storerespon amb el nom d’usuari i la contrasenya que vam guardar abans.
Aquí tens com es veu el fitxer ~/git.store:
https://bob:s3cre7@mygithostÉs només una sèrie de línies, cadascuna de les quals conté una URL decorada amb credencials. Els ajudants osxkeychain i wincred utilitzen el format natiu dels seus emmagatzematges de suport, mentre que cache utilitza el seu propi format en memòria (que cap altre procés pot llegir).
Donat que git-credential-store i els seus amics són programes separats de Git, no és un gran salt adonar-se que qualsevol programa pot ser un ajudant de credencials de Git. Els ajudants proporcionats per Git cobreixen molts casos d’ús comuns, però no tots. Per exemple, diguem que el teu equip té algunes credencials que es comparteixen amb tot l’equip, potser per a desplegament. Aquestes es guarden en un directori compartit, però no vols copiar-les al teu propi emmagatzematge de credencials, perquè canvien sovint. Cap dels ajudants existents cobreix aquest cas; veiem què caldria per escriure el nostre propi. Hi ha diverses característiques clau que aquest programa necessita tenir:
-
L’única acció a la qual necessitem prestar atenció és
get;storeierasesón operacions d’escriptura, així que simplement sortirem netament quan es rebin. -
El format de fitxer del fitxer de credencials compartides és el mateix que el utilitzat per
git-credential-store. -
La ubicació d’aquest fitxer és bastant estàndard, però hauríem de permetre a l’usuari passar una ruta personalitzada per si de cas.
Una vegada més, escriurem aquesta extensió en Ruby, però qualsevol llenguatge funcionarà sempre que Git pugui executar el producte final. Aquí tens el codi font complet del nostre nou ajudant de credencials:
link:../git-credential-read-only[role=include]-
Aquí analitzem les opcions de la línia de comandes, permetent a l’usuari especificar el fitxer d’entrada. El valor per defecte és
~/.git-credentials. -
Aquest programa només respon si l’acció és
geti el fitxer de suport existeix. -
Aquest bucle llegeix de stdin fins que s’arriba a la primera línia en blanc. Les entrades es guarden a l’hash
knownper a referència posterior. -
Aquest bucle llegeix el contingut del fitxer d’emmagatzematge, buscant coincidències. Si el protocol, l’amfitrió i el nom d’usuari de
knowncoincideixen amb aquesta línia, el programa imprimeix els resultats a stdout i surt.
Guardarem el nostre ajudant com a git-credential-read-only, el posarem en algun lloc del nostre PATH i el marcarem com a executable. Aquí tens com es veu una sessió interactiva:
$ git credential-read-only --file=/mnt/shared/creds get
protocol=https
host=mygithost
username=bob
protocol=https
host=mygithost
username=bob
password=s3cre7Com que el seu nom comença amb “git-”, podem utilitzar la sintaxi simple per al valor de configuració:
$ git config --global credential.helper 'read-only --file /mnt/shared/creds'Com pots veure, estendre aquest sistema és bastant senzill, i pot resoldre alguns problemes comuns per a tu i el teu equip.