【问题标题】:Discord oauth2 with php不和谐 oauth2 与 php
【发布时间】:2021-10-23 01:26:22
【问题描述】:

我正在尝试使用 disocrd 的 oauth2 创建登录系统。

这是我的代码:

  <?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    ini_set('max_execution_time', 300); //300 seconds = 5 minutes. In case if your CURL is slow and is loading too much (Can be IPv6 problem)
    
    error_reporting(E_ALL);
    
    define('OAUTH2_CLIENT_ID', 'XXXXXXXXXXXXXXXXXXXXXX'); //Your client Id
    define('OAUTH2_CLIENT_SECRET', 'XXXXXXXXXXXXXXXXXXXXXX'); //Your secret client code
    
    $authorizeURL = 'https://discordapp.com/api/oauth2/authorize';
    $tokenURL = 'https://discordapp.com/api/oauth2/token';
    $apiURLBase = 'https://discordapp.com/api/users/@me';
    
    session_start();
    
    // Start the login process by sending the user to Discord's authorization page
    if(get('action') == 'login') {
    
      // Redirect the user to Discord's authorization page
      header('Location: https://discord.com/api/oauth2/authorize?client_id=873917693953191946&redirect_uri=http%3A%2F%2Fbouncerbot.go-atcode.com%2Fauth.php&response_type=code&scope=identify%20email%20connections%20guilds%20gdm.join%20guilds.join%20rpc%20rpc.notifications.read%20rpc.voice.read%20rpc.voice.write');
      die();
    }
    
    
    // When Discord redirects the user back here, there will be a "code" and "state" parameter in the query string
    if(get('code')) {
    
      $token = apiRequest($tokenURL, array(
    "grant_type" => "authorization_code",
    'client_id' => 'XXXXXXXXXXXXXXXX', //censored
    'client_secret' => 'XXX-XXXXXXXXXXXXXXXXXXX',
    'redirect_uri' => 'http://bouncerbot.go-atcode.com/auth.php',
    'code' => get('code')
  ));
      $logout_token = $token->access_token;
      $_SESSION['access_token'] = $token->access_token;
    
    
      header('Location: ' . $_SERVER['PHP_SELF']);
    }
    ?><script> console.log(<? echo $user->username?> )</script><?
    if(session('access_token')) {
      $user = apiRequest($apiURLBase);
    
      echo '<h3>Logged In</h3>';
      echo '<h4>Welcome, ' . $user->username . '</h4>';
      echo '<pre>';
        print_r($user);
      echo '</pre>';
    
    } else {
      echo '<h3>Not logged in</h3>';
      echo '<p><a href="?action=login">Log In</a></p>';
    }
    
    
    if(get('action') == 'logout') {
      // This must to logout you, but it didn't worked(
    
      $params = array(
        'access_token' => $logout_token
      );
    
      // Redirect the user to Discord's revoke page
      header('Location: https://discordapp.com/api/oauth2/token/revoke' . '?' . http_build_query($params));
      die();
    }
    
    function apiRequest($url, $post=FALSE, $headers=array()) {
      $ch = curl_init($url);
      curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    
      $response = curl_exec($ch);
    
    
      if($post)
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
    
      $headers[] = 'Accept: application/json';
    
      if(session('access_token'))
        $headers[] = 'Authorization: Bearer ' . session('access_token');
    
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    
      $response = curl_exec($ch);
      return json_decode($response);
    }
    
    function get($key, $default=NULL) {
      return array_key_exists($key, $_GET) ? $_GET[$key] : $default;
    }
    
    function session($key, $default=NULL) {
      return array_key_exists($key, $_SESSION) ? $_SESSION[$key] : $default;
    }
    
    ?>

问题是当我去授权 discord 然后 discord 将我重定向回 auth.php 时,令牌没有被获取,因此仍然存在:

未登录 登录

我无法弄清楚问题的原因,所以我问了一个问题。这是登录页面:http://bouncerbot.go-atcode.com/auth.php

【问题讨论】:

  • 查看您页面的源 HTML,您似乎只有一个未定义的变量 - Undefined variable: user
  • 未定义但未检索访问令牌,否则输出为:Logged In Welcome,,而是保持Not logged in Log In,因此会话('访问令牌')不存在
  • @Kae 错误消失了,因为我删除了错误的控制台日志,但仍然无法登录,我不明白为什么
  • 腰部重定向中的client_id 应该是OAUTH2_CLIENT_ID 吗?您在链接中有一个静态值...
  • @LarsStegelitz 我尝试直接输入字符串,所以我直接将值作为字符串而不是'client_id' =&gt; OAUTH2_CLIENT_ID, 'client_secret' =&gt; OAUTH2_SECRET_KEY,,但没有任何变化,问题仍然存在

标签: php oauth-2.0 discord


【解决方案1】:

1st) 重定向工作正常,因为您正在使用

'redirect_uri' => 'http://bouncerbot.go-atcode.com/auth.php',

这就是重定向到 auth.php 的原因

2nd)您必须在 discord 应用程序上定义相同的重定向 URL,如下所示:

3rd)创建代码生成页面和重定向页面,您可以在同一个页面上,也可以创建两个单独的页面。

我正在测试创建 2 个页面

1.代码请求(disocrd.php)

 <?php

    define('OAUTH2_CLIENT_ID', '882143362046640112');

    $redirectURL = 'https://localhost/test_project/disocrd_responce.php';

    $params = array(
        'client_id' => OAUTH2_CLIENT_ID,
        'redirect_uri' => $redirectURL,
        'response_type' => 'code',
        'scope' => 'identify guilds'
    );

    // Redirect the user to Discord's authorization page
    header('Location: https://discord.com/api/oauth2/authorize' . '?' . http_build_query($params));
    die();
    ?>

点击此页面后,页面将自动重定向到 https://localhost/test_project/disocrd_responce.php 代码

2。使用代码生成令牌(disocrd_responce.php)

<?php

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
ini_set('max_execution_time', 300); //300 seconds = 5 minutes. In case if your CURL is slow and is loading too much (Can be IPv6 problem)

error_reporting(E_ALL);

$code = isset($_REQUEST['code']) ? $_REQUEST['code'] : '';

define('OAUTH2_CLIENT_ID', '882143362046640112');
define('OAUTH2_CLIENT_SECRET', 'hYvpAl_heUJNC0veaoraMxNhJL2fgHVU');

$authorizeURL = 'https://discord.com/api/oauth2/authorize';
$tokenURL = 'https://discord.com/api/oauth2/token';
$redirectURL = 'https://localhost/test_project/disocrd_responce.php';

if(get('code')) {

  session_start();

  // Exchange the auth code for a token
  $token = apiRequest($tokenURL, array(
    "grant_type" => "authorization_code",
    'client_id' => OAUTH2_CLIENT_ID,
    'client_secret' => OAUTH2_CLIENT_SECRET,
    'redirect_uri' => $redirectURL,
    'code' => get('code')
  ));
  $logout_token = $token->access_token;
  $_SESSION['access_token'] = $token->access_token;

  echo "<pre>"; print_r($token); exit; // get token properly
// header('Location: ' . $_SERVER['PHP_SELF']);
}

function apiRequest($url, $post=FALSE, $headers=array()) {
  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

  $response = curl_exec($ch);


  if($post){
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
  }
  $headers[] = 'Accept: application/json';

  if(isset($_SESSION['access_token']))
    $headers[] = 'Authorization: Bearer ' . $_SESSION['access_token'];

  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

  $response = curl_exec($ch);
  return json_decode($response);
}

function get($key, $default=NULL) {
  return array_key_exists($key, $_GET) ? $_GET[$key] : $default;
}

?>

当我像这样打印令牌时:

echo "<pre>"; print_r($token); exit;

我们像这样正确地获得了令牌:

 stdClass Object
 (
   [access_token] => 'FBLOYotKRxe0uO7KJcS8mfce5z9YEE'
   [expires_in] => 604800
   [refresh_token] => FxlsNH06OHcbMCJlAZhWzbi4DsIjUO
   [scope] => identify guilds
   [token_type] => Bearer
 )

注意:从安全角度来看,我更改了客户 ID 和令牌

【讨论】:

【解决方案2】:

您在测试时会在重定向 URL 中得到答案:

http://bouncerbot.go-atcode.com/auth.php?error=invalid_scope&error_description=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed.

尝试只询问email,看看它是否有效。如果它确实继续添加内容,直到您找到导致问题的原因。

【讨论】:

  • 我试着照你说的去做,或者只放电子邮件。该错误不存在,但我的问题中提到的相同问题仍然存在
  • 是什么原因造成的:“error=invalid_scope&error_description=The+requested+scope+is+invalid%2C+unknown%2C+or+malformed”是这样的:applications.builds.upload 但它没有解决我真正的问题
猜你喜欢
  • 2021-01-27
  • 2022-01-20
  • 2021-01-10
  • 2021-02-14
  • 2022-10-13
  • 2017-08-12
  • 2021-03-25
  • 2021-10-19
  • 2022-08-04
相关资源
最近更新 更多