Githubでhttpsを使っているのに403: Permission denied エラーが出た話
はじめに
gitを利用するすべての初心者に捧げます。
タイトルのとおりです。gitで利用している認証ヘルパーについての話があります。
目次
検証環境
$ sw_vers ProductName: Mac OS X ProductVersion: 10.11.6 BuildVersion: 15G1510 $ uname -a Darwin hal0taso-2.local 15.6.0 Darwin Kernel Version 15.6.0: Tue Apr 11 16:00:51 PDT 2017; root:xnu-3248.60.11.5.3~1/RELEASE_X86_64 x86_64 $ git --version git version 2.10.1 (Apple Git-78)
問題の概要
githubでpushすると以下のようなエラーが出ます。403 Forbiddenというやつです。
git push -u origin master remote: Permission to hal00taso/test403error.git denied to hal0taso. fatal: unable to access 'https://github.com/hal00taso/test403error.git/': The requested URL returned error: 403
おかしい….httpsを使っているはずなのに…と思って調べてみました
原因
原因は、リポジトリhal00taso/test403error
にpushする権限を持たないユーザーhal0taso
(今回のケースでは0
が一つ多いことに注意してください)でpushしようとしているためです。
リモートリポジトリにhttp(s)で接続していて認証が必要な場合には、基本的には毎回ログインを求められます。また、二段階認証が必要なシステムの場合、そのトークンはランダムかつunpronounceableなため、更に大変になります。この煩わしさを回避するためにGit にはcredential helperという認証情報を一時的、半永久的に記憶する仕組みがあり、ユーザーがいちいち認証情報を入力する手間を省いてくれます。特にmacではcredential helperにosxkeychain
を設定することで、Macのキーチェーンアクセスで管理された認証情報を使用します。
そこで、現在有効になっている設定を確認してみましょう。
$ git config --list credential.helper=osxkeychain user.name=hal0taso user.email=[YOUR EMAIL] core.excludesfile=/Users/hal0taso/.gitignore_global
1行目を確認すると、確かにcredengial helperが有効になっていることが確認できます。
これはデフォルトの場合パスを無視してしまうため、前回github.com
にログインしたユーザー名で認証しようとして失敗することが原因です。
対策
この対策としては以下の4つが挙げられます。
https://hal00taso@github.com/
としてURLにユーザー名を含める- 全く記憶しないようにする: configから
credential.helper
を消す - 記憶している情報を消す:
git credential reject
コマンドを使う - 記憶する際にパスも考慮するようにする:
credential.useHttpPath
をtrue
にする - Macの場合、osx-keychainの認証情報を更新する
[2017/7/4追記]
hub
コマンドを使えという嬉しいマサカリが id:jtwp470 から飛んできたので、こちらに追記させていただきます。hub
コマンドも対策必要です。
github.com
なお、gitの設定とそれが記述されているファイルパスは以下のようにして調べることができます。
$ git config --list --show-origin file:/Applications/Xcode.app/Contents/Developer/usr/share/git-core/gitconfig credential.helper=osxkeychain file:/Users/hal0taso/.gitconfig user.name=hal0taso file:/Users/hal0taso/.gitconfig user.email=[YOUR EMAIL] file:/Users/hal0taso/.gitconfig core.excludesfile=/Users/hal0taso/.gitignore_global
これを確認してみると、Macの場合はXcodeによって設定されているようです。
macでのOSX Keychainシステムの認証情報の更新、削除に関しては以下のリンクを参照してください。OSX Keychainシステムとは、Keychain Access.app
から認証情報を取得する仕組みのことです。
Updating credentials from the OSX Keychain - User Documentation
[おまけ] git credential helperの裏側
さて、ではcredential helperはどのようにして動作しているのでしょうか。Gitのcredential helperのための基本的なコマンドはgit credential
です。これは、コマンドに引数を渡して、更に標準入力から必要な情報をとって利用されます。
例をみてみましょう。以下のようにgit credential fill
と端末上で入力することで、Git-credentialの対話モードを開始することができます。
$ git credential fill protocol=https host=github.com protocol=https host=github.com username=hal0taso password=PASSWORD
まず、Git-credentialは標準入力からの入力を待機します。ここでは現在わかっている情報である、プロトコル(https
)とホスト名(github.com
)を入力します。空白行を渡すことでGit-credentialに入力が完了したことを知らせます。すると、その入力にヒットした内容が標準出力に表示されます。
この情報を渡すことによって、ユーザーは認証情報を入力する必要がなくなります。
より詳しい解説はGitの以下のページにあるので、そちらを読んでみることをおすすめします。
参考
Updating credentials from the OSX Keychain - User Documentation
git - githubへgit pushしようとすると403エラーとなる - スタック・オーバーフロー
osx - How do you reset the stored credentials in 'git credential-osxkeychain'? - Stack Overflow