# \[SOLVED\] Client Credentials 401 Unauthorized Javascript Node Fetch Request

**URL:** <https://forums.combatlogforums.com/t/solved-client-credentials-401-unauthorized-javascript-node-fetch-request/15363>\
**Category:** General\
**Created:** [February 25, 2024, 10:27am UTC](https://forums.combatlogforums.com/t/solved-client-credentials-401-unauthorized-javascript-node-fetch-request/15363 "2024-02-25T10:27:14Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Marbo](https://avatars.discourse-cdn.com/v4/letter/m/e99b99/32.png) [@Marbo](https://forums.combatlogforums.com/u/Marbo)\
**Post date:** [February 25, 2024, 10:27am UTC](https://forums.combatlogforums.com/t/solved-client-credentials-401-unauthorized-javascript-node-fetch-request/15363/1 "2024-02-25T10:27:14Z")

</div>

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](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](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](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](https://www.warcraftlogs.com/api/clients/)

// and fill in the following

Client\_ID=`Your Client ID`

Client\_Secret=`Your Client Secret`
