Hello guys!
Currently Im trying to do an Discord OAuth Authentication for my game dashboard so the user can link his Discord Account in the game but im facing some issues when doing the following call via nk.httpRequest:
https://discord.com/api/oauth2/token
It appears to return the error indicated by discord documentation:
In accordance with the relevant RFCs, the token and token revocation URLs will only accept a content type of application/x-www-form-urlencoded. JSON content is not permitted and will return an error.
The current nk.httpRequest implementation seems to still send a JSON Body when doing a
‘Content-Type’: ‘application/x-www-form-urlencoded’ request
- Versions: Nakama {3.21.0}, {Docker}, {Nakama Common 1.31.0}
- Server Framework Runtime language {TS/JS}
This is my implementation:
export function connectDiscordRpc(ctx: nkruntime.Context, logger: nkruntime.Logger, nk: nkruntime.Nakama, payload: string): string {
let parsedPayload = JSON.parse(payload) as DiscordAuthPayload
const discordClientId = ctx.env.discordClientId
const discordClientSecretId = ctx.env.discordClientSecretId
const discordRedirectUrl = ctx.env.discordRedirectUrl
if (
!discordClientId ||
!discordClientSecretId ||
!discordRedirectUrl ||
discordClientId === '' ||
discordClientSecretId === '' ||
discordRedirectUrl === ''
) {
throw FormatGRPCError('Discord environment variables not set', nkruntime.Codes.INTERNAL)
}
const body = {
grant_type: 'authorization_code',
code: parsedPayload.code,
redirect_uri: discordRedirectUrl,
}
const authEncoded = nk.base64Encode(`${discordClientId}:${discordClientSecretId}`)
logger.info('Discord Auth Body: %#v', body)
const headers = {
'Authorization': `Basic ${authEncoded}`,
'Content-Type': 'application/x-www-form-urlencoded',
}
logger.info('Discord Headers: %#v', headers)
const request = nk.httpRequest(discordAuth, 'post', headers, JSON.stringify(body))
logger.info('Discord Auth Response: %#v', request)
if (request.code !== 200) {
throw FormatGRPCError('Failed to connect to Discord', nkruntime.Codes.PERMISSION_DENIED)
}
/// Rest of the code
return JSON.stringify({ success: true })
}
this is the log:
{"msg":"Discord Auth: \"MTI...==\"","rpc_id":"connectdiscordrpc"}
{"msg":"Discord Auth Body: \"{\\\"grant_type\\\":\\\"authorization_code\\\",\\\"code\\\":\\\"9E12...\\\",\\\"redirect_uri\\\":\\\"https://testnet-...\\\"}\"","rpc_id":"connectdiscordrpc"}
{"msg":"Discord Auth Response: \"{\\\"code\\\":400,\\\"headers\\\":{\\\"Content-Security-Policy\\\":[\\\"frame-ancestors 'none'; default-src 'none'\\\"],\\\"Alt-Svc\\\":[\\\"h3=\\\\\\\":443\\\\\\\"; ma=86400\\\"],\\\"Cf-Ray\\\":[\\\"878ca3092fd35e19-MAD\\\"],\\\"X-Content-Type-Options\\\":[\\\"nosniff\\\"],\\\"Server\\\":[\\\"cloudflare\\\"],\\\"Content-Type\\\":[\\\"application/json\\\"],\\\"Nel\\\":[\\\"{\\\\\\\"success_fraction\\\\\\\":0,\\\\\\\"report_to\\\\\\\":\\\\\\\"cf-nel\\\\\\\",\\\\\\\"max_age\\\\\\\":604800}\\\"],\\\"Report-To\\\":[\\\"{\\\\\\\"endpoints\\\\\\\":[{\\\\\\\"url\\\\\\\":\\\\\\\"https:\\\\\\\\/\\\\\\\\/a.nel.cloudflare.com\\\\\\\\/report\\\\\\\\/v4?s=NqbhQ%%%\\\\\\\"}],\\\\\\\"group\\\\\\\":\\\\\\\"cf-nel\\\\\\\",\\\\\\\"max_age\\\\\\\":604800}\\\"],\\\"Via\\\":[\\\"1.1 google\\\"],\\\"Cf-Cache-Status\\\":[\\\"DYNAMIC\\\"],\\\"Content-Length\\\":[\\\"42\\\"],\\\"Set-Cookie\\\":[\\\"__dcfduid=; Expires=Sun, 22-Apr-2029 08:55:50 GMT; Max-Age=157680000; Secure; HttpOnly; Path=/; SameSite=Lax\\\",\\\"__sdcfduid=; Expires=Sun, 22-Apr-2029 08:55:50 GMT; Max-Age=157680000; Secure; HttpOnly; Path=/; SameSite=Lax\\\",\\\"__cfruid=-; path=/; domain=.discord.com; HttpOnly; Secure; SameSite=None\\\",\\\"_cfuvid=; path=/; domain=.discord.com; HttpOnly; Secure; SameSite=None\\\"],\\\"Strict-Transport-Security\\\":[\\\"max-age=31536000; includeSubDomains; preload\\\"],\\\"Date\\\":[\\\"Tue, 23 Apr 2024 08:55:50 GMT\\\"]},\\\"body\\\":\\\"{\\\\\\\"message\\\\\\\": \\\\\\\"400: Bad Request\\\\\\\", \\\\\\\"code\\\\\\\": 0}\\\"}\"","rpc_id":"connectdiscordrpc"}
This is a problem with the httpRequest or how Im formating the body to x-www-form-urlencoded?
When trying to do the same post call with postman it works.