GitLabで2段階認証を導入したらSourceTreeで弾かれた話(Windows)

こんばんは。
今回の内容はタイトルの通りです。
仕組み的にはGithubでも同じことが起きます。
ただ、GithubとBitBucketはSourceTreeのホスティングサービス(認証サービス)が対応してくれているので楽だと思います。

# 問題が起きた環境
・Windows10
・SourceTree(Git)
・GitLab
(公開設定がPrivateなど限定されているRepository、Publicなリポジトリでは起きないはず)

# 問題の起きる原因
Gitlabで2段階認証を設定すると、
SourceTree(バージョン管理ツール)や自動化ツール(CI)などの外部サービスからの認証方式が
APIToken以外受け付けなくなる。

結果、SourceTreeでPull&Push&Fetchができなくなる。

※ BitBucketについては[こちら](https://ja.confluence.atlassian.com/bitbucket/two-step-verification-777023203.html#Two-stepverification-Troubleshootingtwo-stepverification)
※ Githubに関しても同様でHttpでの認証ができなくなるので、APITokenつかったりSSH認証を使いましょう。こちらは日本語のブログいっぱいあるので、簡単です。


# 解決方法
### 方法1 APITokenで認証を行うようにする
難しいことはありません。
#### 【手順1】APITokenを発行する
GitLabページの右上にあるUserメニューより「Settings」を選択してUserSettingsを開きます。
左の「Access Tokens」よりAPITokenを作成します。
**「Name」** はなんでもいいです。覚えれる名前にしてください。
**「Expires at」** これは発行するAPITokenがいつまで使えるようにするか期限を指定してください
**「Scopes」** このAPITokenで何ができるか指定します
**api** にチェックを入れるとリポジトリやグループをフル操作できるようになり、
**read_user**にチェック入れると個人情報が読み込めるようになるっぽい
今回は両方チェック入れましたが、用途に合わせて最小限にした方が良さそうですね。
設定が決まったら「Create Personal Access Token」で作成しましょう。
ページの上の方にトークンが表示されますが、一度しか表示されませんのでちゃんとMemoしましょう。
画像なくてごめんなさい。

このTokenをSourceTreeのパスワード入力の方に使えば、
SourceTreeでAPIToken認証をしてGitlabリポジトリに操作ができるようになります。
#### 【手順2】 SourceTreeでパスワード入力の際にAPITokenを使用する
さっきいったじゃん！って思うと思いますが、
原理は簡単ですが勘違いしないようちゃんと説明します。

今まで、SourceTreeでPullやPushする際にすでにパスワードを入力していたと思います。
ユーザー名はGitlabのユーザー名を使い、パスワードは先ほど生成したAPITokenを使用してください。

もしパスワード聞かれないけど？って方がいたら
**”Git Credential Manager for Windows”**がパスワードをキャッシュしていて裏で勝手に認証していると思います。
なにが起こるか？
はい。このManagerがパスワードとして今まで使っていたHTTPSのパスワードを勝手に送るので、APITokenを入力できずに、操作に失敗します。
詳細を確認すると「remote: http basic access denied」とか言われます。4度ほど。

それは困るので、一旦キャッシュを削除するか、**”Git Credential Manager for Windows”**の設定を変更しましょう。
キャッシュを一度削除すれば、一度だけ入力する画面がでてくるようになるのでGitlabユーザー名とAPITokenを入力してください。
ただ、APITokenの期限がきれたらまた、操作できなくなるはずです。
困りますね。

【保存されたパスワードの削除の仕方】
「コントロール パネル\すべてのコントロール パネル項目\資格情報マネージャー」に移動してください。
2つ画像が表示されていると思いますが、右の「Windows資格情報」を選択してください。
するとGitlabに関する資格情報が保存されているので、削除します。
いくつかあるかもしれませんが、見分けがつかないので適当に削除しました。
(削除の方が編集するよりは確実だと思います)
これで次回の一度だけユーザー名とパスワードが聞かれ、入力した内容は再度保存されます。
[参考サイト](https://stackoverflow.com/questions/15381198/remove-credentials-from-git/15382950?stw=2#15382950)

【Git Credential Manager for Windowsの設定を変更する】
”Git Credential Manager for Windows”をアンインストールしてしまうか、コマンドで設定を変更します。
ここについては、そんなに難しい話はありませんが
詳しくないので、サイトを紹介させてください。
一応下記のコマンドで現在の設定が確認できます
```git config --get credential.helper```
私は　Manager　になってました。
`git config --global credential.helper ほげほげ`で設定できるのでほげほげをmanagerにすれば私の場合は設定が戻せるわけです。
保存せずに、毎回ユーザー名とパス聞いてほしい場合は
`git config --unset credential.helper`を実行すれば毎回聞かれるようになります。面倒ですが。

[Git公式(credential.helperの設定”manager”については書いてないけど基本がわかります)](https://git-cm.com/book/ja/v2/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E8%AA%8D%E8%A8%BC%E6%83%85%E5%A0%B1%E3%81%AE%E4%BF%9D%E5%AD%98)
[参考サイトGitHubでhttps：//を使用する際に、パスワードの入力をスキップする方法はありますか？(StackOverflow)](https://stackoverflow.com/questions/5343068/is-there-a-way-to-skip-password-typing-when-using-https-on-github)
[Gitから資格を削除する(StackOverflow)](https://stackoverflow.com/questions/15381198/remove-credentials-from-git/15382950?stw=2#15382950)
申し訳ございませんが、下手な説明をするよりもいいと思ったので、ご容赦ください。

### 方法2　2段階認証をやめる
これは冗談で言っているのではなくて、プロジェクトの人数が多くなるのを想像してみてほしいです。
なぜなら方法1で紹介する方法をプロジェクト全員がやらなければならない。PCに不慣れな人がいたとしても。

APITokenには期限(自分で設定できます)があるので「急にSourceTreeが動かなくなった」とか言い出す人が出てきても仕方がないのです。プロジェクト終了後まで面倒が見切れるとは限りません。
「APITokenの期限が○○で切れるから、その時は再発行するか、プロジェクト終了後だったらもう必要ないから設定戻してね。手順書は作っといたよ」とか伝えたとしても果たして何人がその言っている内容を理解できるだろうか。そして手順書を作ったとしてもそれまでに変更がない保証はありません。

「方法が2つあると言ったな。あれは嘘だ。」

拙いブログですが、最後まで見てくださりありがとうございました。
みなさん、良いエンジニアライフを！