Git
Chapters ▾ 2nd Edition

7.14 Mga Git na Kasangkapan - Kredensyal na ImbakanCredential Storage

Kredensyal na ImbakanCredential Storage

Kung ikaw ay gagamit ng SSH transport para sa pagkonekta ng mga remote, ito ay posible para sa iyo na magkaroon ng isang susi na walang isang passphrase, na kung saan ay nagpapahintulot sa iyo ng ligtas na paglipat ng datos na walang pag-type ng iyong username at password. Gayunpaman, ito ay hindi posible sa HTTP na mga protocol – sa bawat koneksyon ay nangangailangan ng isang username at password. Ito ay naging mas mahirap para sa mga sistema na may dalawang-factor sa pagpapatotohanan, na kung saan ang token na iyong ginamit para sa password ay sapalaran na nabuo at hindi mabibigkas.

Sa kabutihang-palad, ang Git ay merong maraming mga kredensyal na sistema na maaari makakatulong para dito. Ang Git ay mayroong ilang mga opsyon na makikita sa ibinigay na kahon:

  • Ang default ay hindi na-cache sa lahat. Sa bawat koneskyon ay mayroong lumalabas para sayong username at password.

  • Ang “cache” na mode ay nagpapanatili ng mga kredensyal sa memorya para sa isang tiyak na oras. Wala sa mga password ang na-imbak sa disk, at sila ay nalinis mula sa cache pagkatapos ng 15 minuto.

  • Ang “store” na mode ay sine-save ang mga kredensyal sa isang plain-teksyo sa disk, at sila ay hindi pa na-expire. Nangangahulugan ito na hanggang binago mo ang iyong password para sa Git host, ay hindi ka na kailanman kailangan i-type ang iyong kredensyal muli. Ang kakulangan sa lapitan na ang iyong password ay naka-imbak sa cleartext sa isang plain file sa iyong home na direktoryo.

  • Kung ikaw ay gumagamit ng Mac, ang Git ay mayroong isang “osxkeychain” na mode, na may mga cache na mga kredensyal sa isang ligtas na keychain na naka-attach sa sistema ng iyong account. Ang paraang ito ay nag-iimbak ng mga kredensyal sa disk, at hindi sila mag-expire, ngunit sila ay naka-encrypt na may parehong sistema na nag-iimbak ng HTTPS na mga sertipiko at ang Safari ay awtomatikong nagpupuna.

  • Kung ikaw ay gumagamit ng Windows, maaari kang mag-install ng tumutulong na nagngangalang “Git Credential Manager for Windows.” Ito ay katulad sa “osxkeychain” na tumutulong sa paglalarawan sa itaas, ngunit gumagamit ng Windows Credential Store upang i-kontrol ang sensitibong impormasyon. Ito ay maaaring matagpuan sa https://github.com/Microsoft/Git-Credential-Manager-for-Windows.

Maaari kang pumili sa isa sa mga pamamaraan ng pagtatakda ng halaga sa kompigurasyon ng Git:

$ git config --global credential.helper cache

Marami sa mga tumutulong ay mayroong mga opsyon. Ang “store” na katulong ay maaaring kumuha ng isang --file <path> na argumento, na kung saan ay which nagpapasadya sa kung saan ang plain-teksto na file ay naka-save (ang default ay ~/.git-credentials). Ang “cache” na katulong ay tumatanggap ng --timeout <seconds> na opsyon, na kung saan ay nagbabago sa halaga ng oras sa kanyang daemon ay pinanatiling tumatakbo (ang default ay “900”, o 15 minuto). Ito ang isang halimbawa kung paano mo siya paano mo ikompigura ang “store” na katulong na may isang pasadyang pangalan ng file:

$ git config --global credential.helper 'store --file ~/.my-credentials'

Ang Git ay nagpapahintulot kahit na ikaw ay magkompigura nang maraming mga katulong. Kapag naghahanap ng mga credential para sa isang partikular na host, Ang Git ay magtanong sa kanila sa pagkasunod-sunod, at ihinto pagkatapos ang unang sagot ay ibinigay. Kapag nag-save sa mga credential, Ang Git ay nagpapadala ng username at password sa lahat ng mga katulong na nasa listahan, at sila ay maaaring pumili kung ano ang gagawin nila. Narito kung ano ang isang .gitconfig na itsura kung ikaw ay mayroong isang credential na file sa isang thumb drive, pero gustong gumagamit ng in-memory cache upang i-save ang ilang mga pag-type kung ang drive ay hindi nakapasok:

[credential]
    helper = store --file /mnt/thumbdrive/.git-credentials
    helper = cache --timeout 30000

Sa ilalim ng Hood

Paano ang lahat ng ito ay gumagana? Ang root na utos ng Git para sa credential-katulong na sistema ay git credential, na kung saan ay kumukuha ng utos bilang isang argumento, at pagkatapos maraming input sa pamamagitan ng stdin.

Maaaring mas madali ito na maunawaan na may isang halimbawa. Sabihin natin na ang isang crendential na katulong ay nakompigura na, at ang katulong ay naka-imbak ng mga credential para sa mygithost. Ito ang sesyon na gumagamit ng “fill” na utos, na kung saan ay tumatawag kapag ang Git ay sumusubok na tingnan ang mga credential para sa isang host:

$ 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
  1. Ito ay ang command line na nagpapasimula sa pakikipag-ugnayan.

  2. Ang Git-credential ay naghihintay para sa input sa stdin. Kami ay nagbibigay nito na may bagay na alam namin: ang protocol at hostname.

  3. Isang blangko linya to Isang blangko na linya ano ang alam to ano ang alam nito, at ang credential na sistema ay dapat sagutin na kung ano ang alam.

  4. Ang Git-credential pagkatapos pumalit, at sumusulat sa stdout na may mga bit ng impormasyon na nakita.

  5. Kung ang mga credential ay hindi matagpuan, Ang Git ay nagtatanong sa gumagamit para sa username at password, at nagbibigay sa kanila pabalik sa hinihinging stdout (narito sila naka-attach sa parehong console).

Ang credential na sistema ay aktwal na tumatawag sa program na naghihiwalay mula sa Git mismo; kung alin at kung papaano depende sa credential.helper na halaga ng configuration. Mayroong maraming mga form na maaaring kumuha:

Configuration Value Behavior

foo

Runs git-credential-foo

foo -a --opt=bcd

Runs git-credential-foo -a --opt=bcd

/absolute/path/foo -xyz

Runs /absolute/path/foo -xyz

!f() { echo "password=s3cre7"; }; f

Code after ! evaluated in shell

Kaya ang mga tumutulong na nilalarawan sa itaas ay aktwal na nagngangalang git-credential-cache, git-credential-store, at iba pa, at maaari kang maka-configure nila na kumuha ng command-line na mga argumento. Ang general form para dito ay “git-credential-foo [args] <action>.” Ang stdin/stdout na protocol ay pareho lang sa git-credential, pero sila ay ginagamit ng bahagyang ibang grupo ng mga aksyon:

  • ang get ay isang hiling para sa username/password na pares.

  • ang store ay isang hiling para i-save ang grupo ng mga credential sa sa memoria ng katulong na ito.

  • ang erase ay naglinis ng mga credential para sa binigay na mga property mula sa memorya ng katulong na ito.

Para sa store at erase na mga aksyon, walang sagot ang kinakailangan (Hindi pa rin pinapansin ng Gitpa). Para sa get na aksyon, gayunpaman, ang Git ay isang napaka interesado na kung ano ang sinasabi ng katulong. Kung ang katulong ay walang anumang alam na magagamit, magagawa itong i-exit na walang output, pero hindi ito alam, dapat dagdagan ang ibinigay na impormasyon na may impormasyon na naka-imbak dito. Ang output ay ginagawang mga serye ng mga assignment na mga pahayag; anumang ibinigay ay papalitan kung ano ang alam na ni Git.

Narito ang parehong halimbawa mula sa itaas, ngunit laktawan ang git-credential at pupuntang tuwid para sa 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
  1. Narito ang aming sasabihin na git-credential-store ay mag-save ng maraming mga credential: ang username na “bob” at ang password “s3cre7” ay gagamitin kapag ang https://mygithost ay pinapasok.

  2. Ngayon ay nakuha na namin ang mga credential na iyon. Nagbibigay kami ng mga bahagi sa koneksyon na alam na namin (https://mygithost), at ang walang laman na linya.

  3. git-credential-store ay sumasagot na may username at password na ipinasok namin sa itaas.

Narito kung ano ang ~/git.store na file na nagmumukha:

https://bob:s3cre7@mygithost

Ito ay isang mga serye ng mga linya lamang, bawat isa ay naglalaman ng crendetial-decorated na UTL. Ang osxkeychain at wincred na mga katulong ay gumgamit ng katutubong format sa kanilang backing na mga tindahan, habang ang cache ay gumagamit ng sariling in-memory na format (na walang ibang proseso na maaaring magbasa).

Ang Pasadyang Credential na Cache

Kung ganoon ang git-credential-store at mga kaibigan ay magkahiwalay ng mga programa sa Git, ito ay hindi gaanong isang paglundag na napagtanto na ang anumang programa ay maaaring isang Git crendetial na katulong. Ang mga katulong ay nagbibigay ng Git na nagtatalakay ng maraming karaniwang gumagamit ng mga kaso, pero hindi lahat. Halimbawa, sabihin natin na ang iyong koponan ay maraming mga credential na ibinahagi sa buong koponan, marahil para sa deployment. Ang mga na-imbak na isang ibinahagi na direktoryo, ngunit ayaw mong ikopya sa iyong sariling imbakan ng credential, dahil madalas silang nagbabago nito. Wala sa mga umiiral na mga katulong ang sumasakop sa kasong ito; tingnan natin kung ano ito at kakailanganin na isulat ang sarili. There are several key features this program needs to have:

  1. Ang tanging aksyon na kailangan natin bigyang pansin ay ang get; store at erase ay sumusulat na mga operasyon, kaya lalabas lang tayo ng malinis kapag sila ay nakatanggap.

  2. Ang file format sa ibinahagi-credential na file ay pareho na ginagamit ng git-credential-store.

  3. Ang lokasyon sa file na iyon ay medyo karaniwan, pero dapat nating pahintulutan na ang gumagamit ay makapasa ng isang pasadyang path kung sakali.

Muli, magsusulat tayo ng extensyon ng Ruby na ito, ngunit ang anumang wika ay gagana hangga’t maipatutupad ng Git ang maaaring magsagawa ng natapos na produkto. Narito ang buong source code sa ating bagong credential na katulong:

#!/usr/bin/env ruby

require 'optparse'

path = File.expand_path '~/.git-credentials' (1)
OptionParser.new do |opts|
    opts.banner = 'USAGE: git-credential-read-only [options] <action>'
    opts.on('-f', '--file PATH', 'Specify path for backing store') do |argpath|
        path = File.expand_path argpath
    end
end.parse!

exit(0) unless ARGV[0].downcase == 'get' (2)
exit(0) unless File.exists? path

known = {} (3)
while line = STDIN.gets
    break if line.strip == ''
    k,v = line.strip.split '=', 2
    known[k] = v
end

File.readlines(path).each do |fileline| (4)
    prot,user,pass,host = fileline.scan(/^(.*?):\/\/(.*?):(.*?)@(.*)$/).first
    if prot == known['protocol'] and host == known['host'] and user == known['username'] then
        puts "protocol=#{prot}"
        puts "host=#{host}"
        puts "username=#{user}"
        puts "password=#{pass}"
        exit(0)
    end
end
  1. Dito namin mai-parse ang command-line na mga opsyon, pumapayag sa gumagamit na magtakda ng input file. Ang default ay ~/.git-credentials.

  2. Ang programa ay tumutugon lamang kung ang aksyon ay get at ang backing-store na file ay umiiral.

  3. Itong loop ay nagbabasa mula sa stdin hanggang ang unang blangkong linya ay naabot. Ang mga input ay na-imbak sa known na hash para sa reperensiya mamaya.

  4. Ang loop ay nagbabasa ng nilalaman sa imbakan ng file, naghahanap ng mga tumutugma. Kung ang protocol at host mula sa known na tugma sa linyang ito, ang programa ay nag-print ng mga resulta sa stdout at umiiral.

I-save namin ang aming mga katulong bilang git-credential-read-only, ilagay ito sa isang lugar sa aming PATH at markahan itong executable. Narito kung ano ang hitsura ng isang interactive na sesyon:

$ git credential-read-only --file=/mnt/shared/creds get
protocol=https
host=mygithost

protocol=https
host=mygithost
username=bob
password=s3cre7

Dahil ang pangalang ito ay na nagsisimula ng “git-”, maaari nating gamitin ang simpleng syntax para sa halaga ng pagsasaayos:

$ git config --global credential.helper 'read-only --file /mnt/shared/creds'

Tulad ng iyong nakikita, pag-extend ng sistemang ito ay medyo tapat, at maaaring maglutas ng ilang karaniwang mga problema para sa iyo at sa iyong koponan