You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? Keep it simple and clear!
Successfully exchanging the authorization code for the access token -
What is the issue? Include screenshots / videos if possible!
data: {
error: ‘invalid_client’,
error_description: ‘Client does not exist’
} -
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I double checked my code, I honestly don’t understand this error. I looked it up online & asked chatGPT for help and none were helpful.
app.js
const crypto = require(‘crypto’);
const axios = require(‘axios’)
const express = require(‘express’)
require(‘dotenv’).config()
const app = express()
app.use(express.static(‘public’))
let redirectURI = encodeURIComponent(“https://holocafe.nwygo.com/authorize”) // Note to self: Would redirect them to /authorize?code={code} | I can then access the code using params with express or smth ig
function base64URLEncode(str) {
return str.toString(‘base64’)
.replace(/+/g, ‘-’)
.replace(///g, ‘_’)
.replace(/=/g, ‘’);
}
console.log(“1”)
function sha256(buffer) {
return crypto.createHash(‘sha256’).update(buffer).digest(base64
);
}
var code_verifier = base64URLEncode(crypto.randomBytes(32));
console.log("Generated code verifier: " + code_verifier);
async function generateCodeChallenge() {
return base64URLEncode(await sha256(code_verifier));
}
var code_challenge;
generateCodeChallenge().then(challenge => {
code_challenge = challenge;
console.log("Generated code challenge: " + code_challenge);
});
console.log(“2”);
console.log(“3”)
async function exchangeWithCode(code) {
console.log("Attempting to exchange code: " + code)
console.log("Using code verifier: " + code_verifier)
let clientsecret = process.env.clientSecret;
let clientid = process.env.clientID;
const response = await axios.post(
‘https://apis.roblox.com/oauth/v1/token’,
new URLSearchParams({
‘client_id’: clientid,
‘client_secret’: clientsecret,
‘grant_type’: ‘authorization_code’,
‘code’: code,
‘code_verifier’: code_verifier
})
);
console.log(response)
return response
}
console.log(“4”)
function exchangeWithRefreshToken(refreshToken) {
const data = new URLSearchParams();
data.append(‘grant_type’, “authorization_code”);
data.append(‘client_id’, process.env[“clientID”]);
data.append(‘client_secret’, process.env[“clientSecret”]);
data.append(‘refresh_token’, refreshToken)
axios.post('https://apis.roblox.com/oauth/v1/token', data, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(response => {
return response
})
.catch(error => {
console.error(error);
return `Failed. Error: ${error}`
});
}
console.log(“5”)
function getUserInfo(authCode) { // OAuth 2.0 Authentication | Documentation - Roblox Creator Hub
axios.get(‘https://apis.roblox.com/oauth/v1/userinfo’, {
headers: {
‘Authorization’: Bearer ${authCode}
}
})
.then(response => {
return response
})
.catch(error => {
console.error(error);
});
}
console.log(“6”)
console.log(“7”)
app.get(‘/authorize’, (req, res) => {
console.log(“Auth get request received”)
if (req.query.code) {
if (req.query.code) {
console.log("Received code: " + req.query.code)
// Successfully authorized. Run code to exchange for token
let exchangeRequest = exchangeWithCode(req.query.code)
console.log("Received the request: " + exchangeRequest)
let token = exchangeRequest.query.access_token
console.log("Access Token: " + token)
let refreshToken = exchangeRequest.query.refresh_token
console.log("Refresh token: " + refreshToken)
let userInfo = getUserInfo(token)
// Add code to store new refreshToken
res.send({ userInfo })
} else {
console.log(`Failed to authorize. Error: ${req.error}. Description: ${req.error_description}. State: ${req.state}`)
res.send("Failed")
}
} else if (req.query.rf == "rf") {
if (req.query.rf) {
// Successfully authorized. Run code to exchange for token
let request = exchangeWithRefreshToken(req.query.rf)
let token = request.query.access_token
let refreshToken = request.query.refresh_token
// Add code to store new refreshToken
} else {
console.log(req)
console.log(`Failed to authorize. Error: ${req.error}. Description: ${req.error_description}. State: ${req.state}`)
res.send("Failed")
}
} else {
res.send("Invalid method")
}
})
console.log(“8”)
app.get(‘/codeverifier’, (req, res) => {
res.send(code_verifier)
})
app.get(‘/codechallenge’, (req, res) => {
res.send(code_challenge)
})
app.get(‘/logout’, (req, res) => {
// will do later – OAuth 2.0 Authentication | Documentation - Roblox Creator Hub
})
console.log(“9”)
app.listen(25024)
console.log(“10”)
script.js
var scopes = [“openid”, “profile”, “group:read”]; // Replace with all the scopes
async function GenerateOAuthURL() {
let code_verifier = await fetch(‘/codeverifier’).then(res => res.text());
let code_challenge = await fetch(‘/codechallenge’).then(res => res.text());
console.log("Code verifier (from client): " + code_verifier);
console.log("Code challenge (from client): " + code_challenge);
let redirectURI = encodeURIComponent("https://holocafe.nwygo.com/authorize") // Note to self: Would redirect them to /authorize?code={code} | I can then access the code using params with express or smth ig
var OAuthURL = "https://apis.roblox.com/oauth/v1/authorize" +
"?client_id=2969482479946332042" +
"&code_challenge=" + code_challenge +
"&code_challenge_method=S256" +
"&redirect_uri=" + redirectURI +
"&scope=" + scopes.join("%20") +
"&response_type=code" +
"&state=abc123";
console.log("OAuthURL:", OAuthURL);
let authButton = document.getElementById('authButton');
authButton.href = OAuthURL;
}
GenerateOAuthURL();
.env
clientID=“**”,
clientSecret=“RBX-****”
Explorer view:
Reason to help me with my problem:
- You get marked as solution if it fixes my problem
- Sense of accomplishments
- Being helpful to community