naj kanál
naj kanál

Reputation: 1

Discord OAUTH2 with node.js

I need discord OAUTH2 login system but i dont know how. I was trying something but it shows me "loginned" again when im not loginned.

i was trying this but i dont know how to do that, if im not loginned that it shows me im not loginned.

const express = require("express")
const fetch = require('node-fetch')
const { URLSearchParams } = require('url')
const app = express()

var config = {
  "clientId": process.env["CLIENT_ID"],
  "clientSecret": process.env['CLIENT_SECRET'],
  "redirectUri": "redirect uri"
}

app.get("/", (request, response) => {
  response.send("login with discord: <a href='redirect url'>login</a>")
})

app.get("/authorize", (request, response) => {
  var code = request.query["code"]
  var params = new URLSearchParams()
  params.append("client_id", config["clientId"])
  params.append("client_secret", config["clientSecret"])
  params.append("grant_type", "authorization_code")
  params.append("code", code)
  params.append("redirect_uri", config["redirectUri"])
  fetch(`https://discord.com/api/oauth2/token`, {
    method: "POST",
    body: params
  })
  .then(res => res.json())
  .then(json => {
    response.send("logged in")
  })
})

app.listen(80, () => {
  console.log("Listening on :80")
})

Upvotes: 0

Views: 3382

Answers (2)

M G Algipari
M G Algipari

Reputation: 9

First you need to install URL for creating url search parameters (can also use form-data). Then install axios (instead node-fetch) for more backwards compatibility work with JSON request, etc. To do so

npm i express url axios path body-parser node-fetch

the code be like

const express = require('express');
const { URLSearchParams } = require('url');
const axios = require('axios');
const path = require('path');
const bodyParser = require('body-parser');
const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));

const client_id = ''; 
const client_secret = '';

//create a new express application and creates a function that will generate headers for a Discord API request.
const app = express(); // Create a web app
const port = 80; // Port to host on
/* this function to make configuration for the Discord API */
function make_config(authorization_token) { 
  data = {
    headers: { 
      "authorization": `Bearer ${authorization_token}`
    }
  };
  return data; 
};

//parse incoming requests of different types
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.use(bodyParser.text());

//when the server receives a GET request, it will send the index.html
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname + '/index.html')); // Send the index.html file
});

//package the data then make a POST request to the Discord API for the authorization token.
app.post('/user', (req, res) => {
  const data_1 = new URLSearchParams();
  data_1.append('client_id', client_id);
  data_1.append('client_secret', client_secret);
  data_1.append('grant_type', 'authorization_code');
  data_1.append('redirect_uri', `http://localhost:${port}/`);
  data_1.append('scope', 'identify');
  data_1.append('code', req.body);
  fetch('https://discord.com/api/oauth2/token', { method: "POST", body: data_1 }).then(response => response.json()).then(data => {

  });
});

axios.get("https://discord.com/api/users/@me", make_config(data.access_token)).then(response => {
  res.status(200).send(response.data.username);
 }).catch(err => {
  console.log(err);
  res.sendStatus(500);
});

app.listen(port, function() {
  console.log(`App listening! Link: http://localhost:${port}/`);
});

The html code that will display a button that will link you to your Discord OAuth2 link. When you are redirected with a code, it will detect the code and make a POST request to your server. When it gets a response, it will display it on a page.

<html lang='en'>

<head>
    <meta charset='utf-8' />
    <title>Discord OAUTH</title>

    <style>
        * {
            text-align: center;
            margin: 0px auto;
        }

        #welcome_txt {
            font-size: 24px;
        }

        #login-link {
            background-color: whitesmoke;
            border-radius: 8px;
            color: black;
            padding: 15px 30px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 20px;
        }

        #login-link:hover {
            cursor: pointer;
        }
    </style>
</head>

<body>
    <br>
    <a id='login-link' href='[DISCORD OAUTH LINK HERE]'>Login with Discord</a><br><br>
    <p id='welcome_txt'></p>

    <script>
        window.onload = function () {
            if (location.href.indexOf("code") !== -1) { // Detect if you logged in or not
                const code = location.href.substring(location.href.indexOf("code") + 5, location.href.length); // Get the code OAUTH gives you
                const req = new XMLHttpRequest(); // Create a new XMLHttpRequest
                req.open("POST", "http://localhost:80/user"); // Open the XMLHttpRequest; CHANGE THE PORT TO THE PORT YOU HAVE AS YOUR VARIABLE IN OAUTH.js.
                req.send(code); // Send the code in the request
                req.onload = () => { // Will run when the request is loaded
                    if (req.status === 500) { // Error
                        document.getElementById('welcome_txt').innerText = `There was an error with that. Please try logging in again. Error Code: ${req.status}`;
                    } else if (req.status === 200) { // Successful
                        document.getElementById("welcome_txt").innerText = `Welcome, ${req.responseText}!`
                    } else { // Other
                        document.getElementById('welcome_txt').innerText = `An error occured. Please try logging in again. Error Code: ${req.status}`;
                    }

                }
            }
        }
    </script>
</body>

</html>

Be sure to paste your OAuth2 link where index.html states [DISCORD OAUTH LINK HERE].

Upvotes: 0

Bench Vue
Bench Vue

Reputation: 9300

Using axis with POST call. It makes life easier.

#1 Setup my App at discord developer portal

enter image description here

#2 Setup OAuth2 at discord developer portal

Add Redirects, Copy Client and Client Secret And give administrator permission (for test purpose)

![enter image description here

#3 Save config.json with Client ID/Secret and Redirects URI

It will use demo.js for get Token API call.

{
    "CLIENT_ID" : "********** your  Client ID *********",
    "CLIENT_SECRET" : "********** your  Client Secret *********",
    "REDIRECT_URI" : "http://localhost:3000/api/callback" <- this should be matched your REDIRECT_URI of Developer Portal
}

#4 Express App Server with demo.js file name.

const express = require("express")
const axios = require('axios')
const config = require('./config.json');

const app = express()

app.get("/login", (request, response) => {
    const redirect_url = `https://discord.com/oauth2/authorize?response_type=code&client_id=${config.CLIENT_ID}&scope=identify&state=123456&redirect_uri=${config.REDIRECT_URI}&prompt=consent`
    response.redirect(redirect_url);
})

app.get("/api/callback", async (request, response) => {
    const code = request.query["code"]
    const resp = await axios.post('https://discord.com/api/oauth2/token',
        new URLSearchParams({
            'client_id': config.CLIENT_ID,
            'client_secret': config.CLIENT_SECRET,
            'grant_type': 'authorization_code',
            'redirect_uri': config.REDIRECT_URI,
            'code': code
        }),
        {
            headers:
            {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        })
    response.send('Logged In: ' + JSON.stringify(resp.data));
})

app.listen(3000, () => {
    console.log("Listening on :3000")
})

#5 Install dependencies and run it

$ npm install express axios
$ node demo.js
Listening on :3000

#6 Access Login page by Chrome

http://localhost:3000/login

It will be forward to discord login page. If shows this screen, press `A button.

enter image description here

Back to call my express URL then display access token and logged in message.

enter image description here

Returned Result this JSON format.

{
    "access_token": "*****************************",
    "expires_in": 604800,
    "refresh_token": "*****************************",
    "scope": "identify",
    "token_type": "Bearer"
}

Upvotes: 2

Related Questions