如何在我的网络应用程序中集成 github 登录 (JavaScript)

Ino*_*ric 3 javascript github github-api cors

我想让用户使用 github 登录我的网络应用程序(之后我可以使用他们的姓名/电子邮件等),就像您可以使用 Google 或 Facebook 登录 stackoverflow 一样。我知道你必须让用户登录 github,一旦他们验证了你的应用程序,你就可以从用户重定向到的页面的 url 中检索代码,并使用该代码发出 POST 请求来获取访问权限代码,您可以使用它来访问 github API。但是,当我对访问代码发出 POST 请求时,出现 CORS 错误:

无法加载https://github.com/login/oauth/access_token?client_id=7...&client_secret=b...&code=f ...:对预检请求的响应未通过访问控制检查:否' Access-Control-Allow-Origin'标头存在于所请求的资源上。因此,不允许访问来源“ http://localhost ”。

响应的 HTTP 状态代码为 404。

这是我的 POST 请求:

$.ajax (
{
    url:"https://github.com/login/oauth/access_token?client_id=7...&client_secret=b...&code=" + authCode, // Extraction of authCode has no bugs



    type:'POST',

    dataType:'json',

    success: function() {
    alert('success');
    },
    error: function() {
    alert('error');
    }

});
Run Code Online (Sandbox Code Playgroud)

如何纠正此问题以便集成登录?

编辑:我无法使用像网守这样的外部应用程序。这是一个测试网站,但最终将用于公司网站。

Joe*_*lis 5

您所要求的非常复杂,大多数 OAuth 应用程序甚至需要经验丰富的开发人员几天甚至几周的时间才能实现。然而,正如你所问的,我会尝试解释它。

首先,您必须注册您的应用程序(https://github.com/settings/applications/new)。您需要知道您的应用程序在哪里。例如,我的位于https://JoelEllis.github.io/github-oauth-app/index.html 然后您将获得一个客户端 ID - 将其保存在某个地方。它会看起来像这样。

接下来,您需要确定您的应用程序需要哪些范围。我将使用read:user,但可用范围的完整列表位于https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/

现在您已经获得了创建将用户发送到的 URL 所需的大部分内容。我将使用 发送它们window.location.href。您的网址将类似于https://github.com/login/oauth/authorize?client_id=<client-id>&redirect_uri=<redirect_uri>&scope=<scope>。我的是https://github.com/login/oauth/authorize?client_id=8681b227337ec96cd168&redirect_uri=https://JoelEllis.github.io/github-oauth-app/index.html&scope=read:user

redirect_uri接下来,GitHub 将使用名为 的参数将您重定向回code,例如https://JoelEllis.github.io/github-oauth-app/index.html?code=3413cabd1c1a8ba9765f。接下来您需要将其转换为访问令牌。

为此,您需要向 URL 发送 post 请求。

不幸的是,如果没有客户端密钥,这是无法完成的,并且在大多数情况下,会被浏览器中的 CORB/CORS 阻止。这意味着在浏览器中获取(或使用)访问令牌是一个非常非常糟糕的主意。客户端秘密永远不应该被泄露,因为它允许攻击者冒充您。

您将需要一台服务器(可以是本地服务器)来完成此后的所有操作。

您可以在 php 中使用读取查询字符串$_GET["code"],在 Nodejs 的 Express 中使用读取查询字符串req.query.code

要发出发布请求,您需要您的client_id、您的client_secret(从您获得客户端 ID 的同一页面)以及 GitHub 提供的代码。您可以使用它们来创建要发布的 URL。它看起来像这样:https://github.com/login/oauth/access_token/?client_id=<clientid>&client_secret=<clientsecret>&code=<usercode>。这是我的:https://github.com/login/oauth/access_token/?client_id=8681b227337ec96cd168&client_secret=6aaf90fef31d8586da40f3eb90cbc478a1e8b948&code=ba82f2915511cea98ea8

要使用 PHP 发布它,您可以使用

$url = 'https://github.com/login/oauth/access_token/';
$data = array('key1' => 'value1', 'key2' => 'value2');

'http' => array(
    'header'  => "Content-type: application/x-www-form-urlencoded\r\nUser-Agent: MyApp",
    'method'  => 'POST',
    'content' => http_build_query($data)
)
$context  = stream_context_create($options);
$result = file_get_contents($url, false, $context);
Run Code Online (Sandbox Code Playgroud)

并使用 Node.js:

var request = require('request')
request.post({
  url: 'https://github.com/login/oauth/access_token/?client_id=847b5bc9c960a03d3435&client_secret=92a2e6ac30db45612c4ed6ee4fbca22a95370807&code=' + req.query.code,
  headers: {
    'User-Agent': 'request'
  }
}, function (error, response, body) {
      console.log('hi2');
      console.log(body);
})
Run Code Online (Sandbox Code Playgroud)

当您发布它时,它会返回类似的内容access_token=7d914db556648258e54a37184c9b07d129ab0891&scope=read%3Auser&token_type=bearer。只需将其添加到请求末尾即可获取响应,例如curl https://api.github.com/user/email?+ access_token=7d914db556648258e54a37184c9b07d129ab0891&scope=read%3Auser&token_type=bearer

完整的文档可以在https://developer.github.com/apps/building-oauth-apps/authorizing-oauth-apps/https://developer.github.com/v3/找到。您可以在https://developer.github.com/v3/users/上查看用于获取有关用户信息的文档