Search code examples
phpoauth-2.0discord

PHP Discord OAUTH2 code sample not working


So this code I found below doesn't work I get to the authenticate screen then when t redirects me it just says Not logged in, Login in again. Does anyone know what I have to do to fix this? I am not very good at OATH2 and would like someone to walk me through.

I used the code from this gist.

<?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', '1234567890');
define('OAUTH2_CLIENT_SECRET', 'verysecretclientcode');

$authorizeURL = 'https://discord.com/api/oauth2/authorize';
$tokenURL = 'https://discord.com/api/oauth2/token';
$apiURLBase = 'https://discord.com/api/users/@me';

session_start();

// Start the login process by sending the user to Discord's authorization page
if(get('action') == 'login') {

  $params = array(
    'client_id' => OAUTH2_CLIENT_ID,
    'redirect_uri' => 'https://yoursite.location/ifyouneedit',
    'response_type' => 'code',
    'scope' => 'identify guilds'
  );

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


// When Discord redirects the user back here, there will be a "code" and "state" parameter in the query string
if(get('code')) {

  // 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' => 'https://yoursite.location/ifyouneedit',
    'code' => get('code')
  ));
  $logout_token = $token->access_token;
  $_SESSION['access_token'] = $token->access_token;


  header('Location: ' . $_SERVER['PHP_SELF']);
}

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;
}

?>

EDIT: Basically in the if statement it doesn't go into the logged-in part.


Solution

  • Here is a working solution

    <?php
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);
    
    session_start();
    $SecretHERE = "";
    $IDHERE = "";
    
    if (isset($_GET["error"])) {
        echo json_encode(array("message" => "Authorization Error"));
    } elseif (isset($_GET["code"])) {
        $redirect_uri = "https://www.devtest.net/v4/login.php";
        $token_request = "https://discordapp.com/api/oauth2/token";
    
        $token = curl_init();
    
        curl_setopt_array($token, array(
            CURLOPT_URL => $token_request,
            CURLOPT_POST => 1,
            CURLOPT_POSTFIELDS => array(
                "grant_type" => "authorization_code",
                "client_id" => $IDHERE,
                "client_secret" => $SecretHERE,
                "redirect_uri" => $redirect_uri,
                "code" => $_GET["code"]
            )
        ));
    
        curl_setopt($token, CURLOPT_RETURNTRANSFER, true);
    
        $resp = json_decode(curl_exec($token));
        curl_close($token);
    
        if (!isset($_SESSION['user']) || !isset($_SESSION['userguilds'])) {
            if (isset($resp->access_token)) {
                $access_token = $resp->access_token;
    
                $info_request = "https://discordapp.com/api/users/@me";
                $info_request_guilds = "https://discord.com/api/users/@me/guilds";
    
                $info = curl_init();
                curl_setopt_array($info, array(
                    CURLOPT_URL => $info_request,
                    CURLOPT_HTTPHEADER => array(
                        "Authorization: Bearer {$access_token}"
                    ),
                    CURLOPT_RETURNTRANSFER => true
                ));
    
                $user = json_decode(curl_exec($info));
                curl_close($info);
    
                // GUILDS REQUEST
                $info_guilds = curl_init();
                curl_setopt_array($info_guilds, array(
                    CURLOPT_URL => $info_request_guilds,
                    CURLOPT_HTTPHEADER => array(
                        "Authorization: Bearer {$access_token}"
                    ),
                    CURLOPT_RETURNTRANSFER => true
                ));
    
                $guilds = json_decode(curl_exec($info_guilds));
                curl_close($info_guilds);
    
                $_SESSION['user'] = $user;
                if ($_SESSION['user']->verified == 1) {
                    $_SESSION['userguilds'] = $guilds;
                    $_SESSION['avatar'] = "https://cdn.discordapp.com/avatars/" . $user->id . "/" . $user->avatar . ".png";
    
                    header("Location: https://www.devtest.net/v4/fork.php");
                    die();
                }else{
                    print_r("Please verify your Discord Account.");
                    session_destroy();
                    die();
                }
    
            } else {
                echo json_encode(array("message" => "Authentication Error"));
            }
        } else{
            // They are already logged in so redirect them to fork.php
            header("Location: https://www.devtest.net/v4/fork.php");
            die();
        }
    } else {
        // Redirect to Discord Oauth2 URL (CAN BE FOUND IN DISCORD DEV PORTAL)
        header('location: https://discord.com/api/oauth2/authorize?client_id=CLIENTIDHERE&redirect_uri=https%3A%2F%2Fwww.devtest.net%2Fv4%2Flogin.php&response_type=code&scope=identify%20email%20connections%20guilds%20guilds.join');
        die();
    }
    
    ?>