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,果然發現存在記錄。

而且,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

原文鏈接:debugtalk.com/post/trap

在微信公眾號debugtalk中輸入Git許可權校驗,獲取《深入淺出Git許可權校驗》。


推薦閱讀:

蘋果強制使用HTTPS傳輸了怎麼辦?——關於HTTPS,APP開發者必須知道的事
如何用機器學習方法,提升另一半的滿意指數?
直擊阿里雙11神秘技術:PB級大規模文件分發系統「蜻蜓」

TAG:GitHub | HTTPS | 权限验证 |