[SOLVED] Client Credentials 401 Unauthorized Javascript Node Fetch Request

I need help because I’m currently smackin’ my noggin into wall trying to get an access token from the the warcraftlogs token url (https://www.warcraftlogs.com/oauth/token) for usage in making javascript api requests in the v2 api.

I’m trying to use client credentials and am using node to send the requests. Not currently using a server, CORS shouldn’t be an issue because the request isn’t being sent from a browser.

Code is entailed:

const clientId = process.env.CLIENT_ID
const clientSecret = process.env.CLIENT_SECRET
const clientCredentials = Buffer.from(${clientId}:${clientSecret}).toString(
‘base64’
)
const tokenUrl = ‘https://www.warcraftlogs.com/oauth/token
const apiUrl = ``

const getAccessToken = async () => {
const response = await fetch(tokenUrl, {
method: ‘POST’,
headers: {
Authorization: Basic ${clientCredentials},
‘Content-Type’: ‘application/x-www-form-urlencoded’,
},
body: ‘grant_type=client_credentials’,
})

return response.json()
}

getAccessToken().then((response) => console.log(response))

Just trying to get the token and then I can take the next steps.
The current error is a 401 so I am making it to the token uri and getting rejected for bad credentials, I’ve just been stumped for hours and I could use a hand, any is appreciated.

Api Url is currently empty because it isnt in use yet.

Current Json error is:

{
error: ‘invalid_client’,
error_description: ‘Client authentication failed’,
message: ‘Client authentication failed’
}

Things I’ve tried:
Making a new client (and updating the env)
Double Checking client id and client secret
btoa vs Buffer.from().toString()
Intentionally messing up headers/body to trigger alternate server responses (400)
Removing trailing ‘==’ from the toString

Edit: Figured it out, it was a problem with .env variables being craptastic like they usually are. This problem made we want to eat my keyboard, but in good news, this javascript works as a client credential flow for the api so feel free to use it if you want. Man I have learned far too much about oauth 2 now for it to be a .env issue.

Edit2: I hadn’t installed ‘dotenv’ node package or imported it PAIN.

Here’s the fixed and working code for those interested:

==========================================
import ‘dotenv/config’

const clientId = process.env.CLIENT_ID
const clientSecret = process.env.CLIENT_SECRET
const clientCredentials = Buffer.from(${clientId}:${clientSecret}).toString(
‘base64’
)
const tokenUrl = ‘https://www.warcraftlogs.com/oauth/token
const apiUrl = ``

const getAccessToken = async () => {
const response = await fetch(tokenUrl, {
method: ‘POST’,
body: ‘grant_type=client_credentials’,
headers: {
Authorization: Basic ${clientCredentials},
‘Content-Type’: ‘application/x-www-form-urlencoded’,
},
})

return response.json()
}

getAccessToken().then((response) => console.log(response))

==========================================

And the .env.sample just in case

==========================================

// Make a client at Warcraft Logs - Combat Analysis for Warcraft

// and fill in the following

Client_ID=Your Client ID

Client_Secret=Your Client Secret