如何通过 curl 获取 GitHub OAuth2 状态代码来模拟 Web 应用程序流程?

How to get GitHub OAuth2 state code via curl to simulate Web Application Flow?

我正在尝试将位于 code.google.com 的几个存储库的代码自动导出到 GitHub(在它们 disappear in the next month 之前!)。

以下是执行此操作的手动过程(例如,对于回购 foo):

  1. https://code.google.com/export-to-github/request-export/foo

    • 这重定向到 https://github.com/login
  2. https://code.google.com/export-to-github/start-export/foo

    • 表格应包含 codestate
  3. https://code.google.com/export-to-github/confirm-export/foo

所以我的方法是通过 curlstart-export 处的表单提交到 confirm-export 并给定 codestate:

<form method="GET" action="/export-to-github/confirm-export/foo">
  <input type="text" hidden="true" name="code" value="GITHUB_CODE">
  <input type="text" hidden="true" name="state" value="FORM_STATE">
  <input class="maia-button" id="confirm-button" type="submit" value="Confirm" tabindex="1">
</form>

我已经知道如何获取最后的表单状态:

curl -s https://code.google.com/export-to-github/start-export/foo | grep -o 'state.\+value=.[^"]\+' | grep -o '[^"]\+$'

但我不知道如何从 GitHub API.

中获取 code

我的 GitHub 凭据存储在 ~/.secrets 中:

$ cat ~/.secrets 
export GITHUB_API_TOKEN=xyz
export GITHUB_CLIENT_ID=xyz

它们可以通过以下方式加载:

. ~/.secrets 

并且通过以下测试它们工作正常:

curl "https://api.github.com/user?access_token=$GITHUB_API_TOKEN"

现在我想获取state字符串,参见:OAuth - Web Application Flow:

state string An unguessable random string. It is used to protect against cross-site request forgery attacks.

似乎这是为 Web 应用程序流程设计的,它不是在以下任何请求中生成的(甚至不确定这是否是正确的终点):

curl "https://api.github.com/authorizations?access_token=$GITHUB_API_TOKEN"

给出错误:

This API can only be accessed with username and password Basic Auth.

以及以下请求:

curl "https://github.com/login/oauth/authorize?access_token=$GITHUB_API_TOKEN"

或:

curl "https://github.com/login/oauth/authorize?access_token=$GITHUB_API_TOKEN&client_id=$GITHUB_CLIENT_ID&amp;redirect_uri=https://code.google.com/export-to-github/start-export/foo&amp;scope=user:email,public_repo,notifications"

returns:

You are being <a href="https://github.com/login?return_to=%2Flogin%2Foauth%2Fauthorize%3Faccess_token%3DSOME_ACCESS_CODE_HERE">redirected</a>

是否有任何非 Web 应用程序流程或其他解决方法来获取 state 我可以使用它来提交表单?

基于以上,我期待这样的结果:

curl -v --data "code=$GITHUB_STATE&state=$(grep -o 'state.\+value=.[^"]\+' https://code.google.com/export-to-github/start-export/foo | grep -o '[^"]\+$')" https://code.google.com/export-to-github/confirm-export/foo

但是目前 returns 错误:

Error getting GitHub user.

因为缺少 code 值,我不知道如何从 GitHub API 中获取它以提交该表单。

解决方案之一是设置 user_session cookie。这可以从 web-browser(在 one-off 登录后)或通过将 user/password 提交到 GitHub 登录表单来获取,并获得正确的 cookie。

然后可以导出为:

export GITHUB_USER_SESSION=xyz

现在,下面的 Bash 脚本很简单:

REPO="foo"
AUTH_PAGE=$(wget -qO- --header="Cookie: user_session=$GITHUB_USER_SESSION" "https://github.com/login/oauth/authorize?access_token=$GITHUB_API_TOKEN&client_id=$GITHUB_CLIENT_ID&amp;redirect_uri=https://code.google.com/export-to-github/start-export/$REPO&amp;scope=user:email,public_repo,notifications")
STATE=$(echo $AUTH_PAGE | grep -o 'name=.\?state[^=]\+value=.[^>]\+')
CODE=$(echo $AUTH_PAGE | grep -o 'name=.\?code[^=]\+value=.[^>]\+')
curl --data "code=$(eval $CODE; echo $value)&state=$(eval $STATE; echo $value)" https://code.google.com/export-to-github/confirm-export/$REPO

在上面的代码中,$AUTH_PAGE 包含身份验证后的源页面(基于用户会话),它具有正确的 codestate 值集。

可选地,页面结果可以通过 | html2text -o "$REPO.txt" 存储到文本文件中(在安装 html2text 之后)。