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

ken*_*orb 5 shell curl oauth github-api access-token

我正在尝试将少数存储库的代码自动导出code.google.com到 GitHub(在它们在下个月消失之前!)。

以下是执行此操作的手动过程(例如 repo 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

所以我的方法是使用start-export给定的and将表单提交到confirm-exportvia :curlcodestate

<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>
Run Code Online (Sandbox Code Playgroud)

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

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

但我不知道如何code从 GitHub API 获取价值。

我的 GitHub 凭证存储为~/.secrets

$ cat ~/.secrets 
export GITHUB_API_TOKEN=xyz
export GITHUB_CLIENT_ID=xyz
Run Code Online (Sandbox Code Playgroud)

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

. ~/.secrets 
Run Code Online (Sandbox Code Playgroud)

通过以下测试,它们工作得很好:

curl "https://api.github.com/user?access_token=$GITHUB_API_TOKEN"
Run Code Online (Sandbox Code Playgroud)

现在我想获取字符串state,请参阅:OAuth - Web 应用程序流程

state string 不可猜测的随机字符串。它用于防止跨站点请求伪造攻击。

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

curl "https://api.github.com/authorizations?access_token=$GITHUB_API_TOKEN"
Run Code Online (Sandbox Code Playgroud)

给出错误:

该API只能通过用户名和密码Basic Auth访问。

并提出以下要求:

curl "https://github.com/login/oauth/authorize?access_token=$GITHUB_API_TOKEN"
Run Code Online (Sandbox Code Playgroud)

或者:

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"
Run Code Online (Sandbox Code Playgroud)

返回:

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

是否有任何非网络应用程序流程或其他解决方法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
Run Code Online (Sandbox Code Playgroud)

但它目前返回错误:

获取 GitHub 用户时出错。

因为该code值丢失,并且我不知道如何从 GitHub API 获取它以提交该表单。

ken*_*orb 4

解决方案之一是设置user_sessioncookie。可以从网络浏览器(一次性登录后)或通过将用户/密码提交到 GitHub 登录表单来获取,并获取正确的 cookie。

然后可以将其导出为:

export GITHUB_USER_SESSION=xyz
Run Code Online (Sandbox Code Playgroud)

现在,以下 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
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,$AUTH_PAGE由身份验证后的源页面(基于用户会话)组成,并且它具有权限codestate值设置。

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