3
3

More than 3 years have passed since last update.

PHP Discord OAuth2認証

Last updated at Posted at 2021-06-23

PHP Discord OAuth2認証

PHP Laravel環境でDiscord OAuth2認証を行ったので備忘録

環境

・Larave 5.7
・PHP 7.2.15

前提

・Discord Developerで「OAUTH2_CLIENT_ID」「OAUTH2_CLIENT_SECRET」を取得
・Discord DeveloperでCallback URLの設定

ログイン時

    public function login(Request $request)
    {
            define('OAUTH2_CLIENT_ID', '<OAUTH2_CLIENT_ID>');
            define('OAUTH2_CLIENT_SECRET', '<OAUTH2_CLIENT_SECRET>');

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


            $params = array(
                'client_id' => OAUTH2_CLIENT_ID,
                'redirect_uri' => '<Callback URL>',
                '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();
    }

Callbackで呼び出す関数

    public function message_login_callback_discord(Request $request)
    {
        define('OAUTH2_CLIENT_ID', '<OAUTH2_CLIENT_ID>');
        define('OAUTH2_CLIENT_SECRET', '<OAUTH2_CLIENT_SECRET>');

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

        if($request->input('code')) {
            // 初回のCallback
            $token = $this->apiRequest($tokenURL, array(
              "grant_type" => "authorization_code",
              'client_id' => OAUTH2_CLIENT_ID,
              'client_secret' => OAUTH2_CLIENT_SECRET,
              'redirect_uri' => '<Callback URL>',
              'code' => $request->input('code')
            ));
            // sessionにaccess_tokenを格納
            session(['access_token' => $token->access_token]);
            return redirect('/message_login_callback_discord');
        }

        //上記処理後のCallback
        if(session('access_token')) {
            $user = $this->apiRequest($apiURLBase);
            $guilds = $this->apiRequest($apiURLGuild);
            return $user;
        }

        return redirect('/login');

    }

その他「API Request 関数」

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

おまけ「特定のDiscordサーバーに参加しているか確認」

            $user = $this->apiRequest($apiURLBase);
            $guilds = $this->apiRequest($apiURLGuild);

            $check_suiseicord_join = false;
            foreach ($guilds as $guild) {
                if ($guild->id=="<確認したいサーバー(guild)のID>") {
                    $check_suiseicord_join = true;
                }
            }
3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3