GitHub 許可權校驗失敗給我的啟發
背景描述
眾所周知,在GitHub中,每個倉庫都有兩個地址,分別基於HTTPS協議和SSH協議,兩個協議對應的URL地址(repository_url)形式如下所示:
# HTTPSnhttps://github.com/DJIXY/MobileStore.gitn# SSHngit@github.com:DJIXY/MobileStore.gitn
正常情況下,只要在本地正確地配置好了git賬號,採用這兩個地址中的任意一個,都可以通過git clone repository_url獲取代碼。
但最近我在Macbook Air中clone公司託管在GitHub私有庫中的代碼時,發現無法通過HTTPS協議的地址clone代碼,始終提示remote: Repository not found.的錯誤。
? git clone https://github.com/DJIXY/MobileStore.gitnCloning into MobileStore...nremote: Repository not found.nfatal: repository https://github.com/DJIXY/MobileStore.git/ not foundn
首先,這個代碼倉庫是確實存在的,而且地址肯定也是沒有問題的,通過URL地址也能在瀏覽器中訪問到對應的GitHub倉庫頁面。
其次,在本地對git的配置也是沒有問題的,通過SSH協議的地址是可以正常clone代碼的。
? git clone git@github.com:DJIXY/MobileStore.gitnCloning into MobileStore...nWarning: Permanently added the RSA host key for IP address 192.30.252.131 to the list of known hosts.nremote: Counting objects: 355, done.nremote: Compressing objects: 100% (3/3), done.n
並且,如果在HTTPS協議的URL地址中加上GitHub賬號,也是可以正常clone代碼的。
? git clone https://djileolee@github.com/DJIXY/MobileStore.gitnCloning into MobileStore...nremote: Counting objects: 355, done.nremote: Compressing objects: 100% (3/3), done.n
更奇怪的是,在我的另一台Mac Mini中,採用同樣的賬號配置,兩種協議的URL地址卻都能正常clone代碼,仔細地對比了兩台電腦的git配置,都是一樣的。
? cat ~/.git-credentialsnhttps://djileolee:340d247cxxxxxxxxf39556e38fe2b0baxxxxxxxx@github.comn?n? cat ~/.gitconfign[credential]n helper = storen
那問題出在哪兒呢?
定位分析
通過Google得知,產生remote: Repository not found.報錯的原因主要有兩個,一是倉庫地址錯誤,二是許可權校驗不通過。顯然,第一個原因可以直接排除,在Macbook Air中出現該問題應該就是賬號許可權校驗失敗造成的。
對背景描述中的現象進行整理,重點關注兩個疑點:
- 通過HTTPS協議的URL地址進行git clone時,系統沒有提示讓輸入用戶名密碼,就直接返回許可權校驗失敗的異常;
- 在HTTPS協議的URL地址中加上GitHub用戶名,就可以正常clone,而且,系統也沒有提示輸入密碼。
這說明,在系統中的某個地方,應該是保存了GitHub賬號密碼的,所以在未指定賬號的情況下,git clone時系統就不再要求用戶輸入賬號密碼,而是直接讀取那個保存好的賬號信息;但是,那個保存的GitHub賬號密碼應該是存在問題的,這就造成採用那個賬號信息去GitHub校驗時無法通過,從而返回異常報錯。
基於以上推測,尋找問題根源的當務之急是找到保存GitHub賬號密碼的地方。
通過查看Git官方文檔,存儲Git用戶信息的地方有三個:
- /etc/gitconfig:存儲當前系統所有用戶的git配置信息;
- ~/.gitconfig或~/.config/git/config:存儲當前用戶的git配置信息;
- 倉庫的Git目錄中的config文件(即repo/.git/config):存儲當前倉庫的git配置信息。
這三個配置項的優先順序從上往下依次上升,即repo/.git/config會覆蓋~/.gitconfig中的配置,~/.gitconfig會覆蓋/etc/gitconfig中的配置。
回到當前問題,由於還沒有進入到具體的Git倉庫,因此repo/.git/config可直接排除;然後是查看當前用戶的git配置,在當前用戶HOME目錄下沒有~/.config/git/config文件,只有~/.gitconfig,不過在~/.gitconfig中並沒有賬號信息;再去查看系統級的git配置信息,即/etc/gitconfig文件,但發現當前系統中並沒有該文件。
找遍了Git用戶信息可能存儲的地方,都沒有看到賬號配置信息,那還可能存儲在哪兒呢?
這時基本上是毫無思路了,只能靠各種胡亂猜測,甚至嘗試採用Wireshark分別在兩台Mac上對git clone的過程進行抓包,對比通訊數據的差異,但都沒有找到答案。
最後,無意中想到了Mac的Keychain機制。在Mac OSX的Keychain中,可以保存用戶的賬號密碼等credentials,那git賬號會不會也保存到Keychain中了呢?
在Macbook Air中打開Keychain Access應用軟體,搜索github,果然發現存在記錄。
而且,http://github.com這一項還存在兩條記錄。一條是我的個人賬號debugtalk,另一條是公司的工作賬號djileolee。
至此,真相大白!!!
在我的Macbook Air中,Keychain Access中保存了我的GitHub個人賬號(debugtalk),該賬號是沒有許可權訪問公司私有倉庫的。但是在Terminal中執行git clone命令時,系統優先讀取了我的個人賬號,並用該賬號向GitHub發起校驗請求,從而造成讀取公司私有倉庫時許可權校驗失敗。然而,在HTTPS協議的URL地址中加上GitHub工作賬號(djileolee)時,由於此時指定了賬號名稱,因此在Keychain中讀取賬號信息時就可以找到對應賬號(包含密碼),並且在無需輸入密碼的情況下就能成功通過GitHub的許可權校驗,進而成功clone得到代碼。
原因弄清楚之後,解決方式就很簡單了,在Keychain中刪除個人賬號,然後就正常了。
總結回顧
但是,問題真的解決了么?
並沒有!
簡單粗暴地在Keychain中將個人GitHub賬號刪除了,雖然再次訪問公司代碼倉庫時正常了,那我要再訪問個人倉庫時該怎麼辦呢?
貌似並沒有清晰的思路。雖然網上也有不少操作指導教程,但是對於操作背後的原理,還是有很多不清晰的地方。
再回到前面的背景描述,以及定位問題的整個過程,不由地悲從中來。使用GitHub好歹也有好幾年了,但是連最基本的概念都還一頭霧水,所以遇到問題後只能靠瞎猜,東碰西撞,最後瞎貓碰到死耗子。
GitHub的HTTPS協議和SSH協議,這本來就對應著兩套完全獨立的許可權校驗方式,而我在HTTPS協議不正常的情況下還去查看SSH協議,這本來就實屬多餘。
藉助這次「掉坑」的經歷,我對Git許可權校驗的兩種方式重頭進行了梳理,並單獨寫了一篇博客,《深入淺出Git許可權校驗》,雖然花了些時間,但總算是掃清了縈繞多年的迷霧,感覺倍兒爽!
如果你也對Git的許可權校驗沒有清晰的了解,遇到許可權校驗出錯時只能「換一種方法試試」,也不知道怎麼讓一台計算機同時支持多個GitHub賬號,那麼也推薦看下那篇博客。
Read More ...
公眾號:DebugTalk
原文鏈接:http://debugtalk.com/post/trap-in-GitHub-authority-verification在微信公眾號debugtalk中輸入Git許可權校驗,獲取《深入淺出Git許可權校驗》。推薦閱讀:
※蘋果強制使用HTTPS傳輸了怎麼辦?——關於HTTPS,APP開發者必須知道的事
※如何用機器學習方法,提升另一半的滿意指數?
※直擊阿里雙11神秘技術:PB級大規模文件分發系統「蜻蜓」