How to use the Roblox Login API (V2) with CAPTCHA

So I did that, here is the request:

app.get('/api/get-captcha', (req, res) => {
  axios.post('https://auth.roblox.com/v2/login', {
    ctype: "Username",
    cvalue: "Removed",
    password: process.env.password,
  })
    .then(() => console.log('Error.'))
    .catch(a => {
      res.json({headers: a.request.res.headers, status: a.request.res.statusCode});
    });
})

This came with the same Forbidden status and the same headers.

1 Like

You need to include ctype, userId, and some captcha fields I can’t recall

Do a login attempt via website with network tab open and inspect the exact fields roblox uses for the request as well as the exact headers (headers is crucial or Roblox won’t authenticate the request)

I was able to successfully get the challenge ID, type, and metadata. However, I have no clue how to render it… I am currently trying to use the node funcaptcha package, but I am struggling. Do I need to create a new captcha token with fun.getToken() or can I go straight to fun.Session()? How do I show this captcha to the client?

When I try fun.getToken() with this code, the token returns as DENIED ACCESS

const token = await fun.getToken({
  pkey: "476068BF-9607-4799-B53D-966BE98E2B81", //This is the login public key for roblox
  surl: "https://roblox-api.arkoselabs.com",
  site: "https://www.roblox.com/login",
})

Here is the package documentation. Thank you so much for your help so far!

~site should be https://www.roblox.com~
^ I may be wrong please test

surl should be without https://

Also when you decode the meta data, extract the blob from it and pass it as additional data

data: {
blob: blob
}

And make sure you are passing realistic headers

1 Like

That is just what I needed! Thank you so much! I have just one more question. The captcha gives me either one with extra data, and one without. The captcha also gives me a challengeID of its own, but roblox gives one also. Where do each of these values go, and where do I find the captchaId for the final login request?

Hello, the challenge id and token go in the headers of the final request. You have to encode the token with action type field to base64 and pass it as the metadata

Sorry, I’m a bit confused. Would it look something like this?

axios.post('https://auth.roblox.com/v2/login', {
	ctype: 0,
	cvalue: `Username`,
	password: process.env.PASS,
	challengeId: challenge.data.challengeID,
	captchaProvider: "PROVIDER_ARKOSE_LABS",
	captchaId: metadata["unifiedCaptchaId"],
}, {
	headers: {
		'Content-Type': 'application/json',
		'x-csrf-token': csrf,
		captchaToken: Buffer.from(token.token).toString('base64'),
		challengeId: challenge.data.challengeID,
	}
}).catch(e => {
	console.log(e.response.data)
})

This logs ‘Challenge is required to authorize the request’.

it shouldn’t be captchaToken, it should be the same name as the meta data field as well as challenge id

You could just buy a cheap dedicated proxy, use it to login, then just proxy the requests on the server. If you have access to the server, you might be able to deploy a simple HTTP proxy or a WireGuard server on it to login using the servers IP.

It’s much better to do it like that because captcha solving services are super unreliable when it comes to solving Funcaptcha and you’ll likely have to sign in manually anyway.

I would do that, however, my project is hosted on Replit and is constantly changing servers and IP addresses.

Would it look something like this? It is still not passing the challenge. I am a little confused on what value goes where still…

await axios.post('https://auth.roblox.com/v2/login', {
	ctype: 1,
	cvalue: `Roblox`,
	password: process.env.PASS,
	challengeId: challenge.data.challengeID,
	captchaProvider: "PROVIDER_ARKOSE_LABS",
	captchaId: metadata["unifiedCaptchaId"],
	captchaToken: token.token,
}, {
	headers: {
		'Content-Type': 'application/json',
		'x-csrf-token': csrf,
		'rblx-challenge-metadata': Buffer.from(JSON.stringify({
			...metadata,
			captchaToken: token.token,
			challengeId: challenge.data.challengeID,
		})).toString('base64')
	}
}).catch(e => {
	console.log(e.response.data)
})

Using an HTTP proxy on the server would still work for this case.

Roblox’s login endpoint is super sensitive about the headers you use when logging in. Axios will use a custom user agent that you need to override when sending a request. I’m pretty sure if you don’t change the user agent, Roblox will detect you as a bot and simply ignore the captcha. I haven’t messed with the login endpoint in a while though so I can’t 100% confirm that’s still the case.

How would I go about setting that up? I will try changing the user agent.

All you’d need to do is find any dedicated (or any other type of static proxy) HTTP proxy provider, then configure your axios client to use said proxy. Then search how to set a proxy in whatever browser you use and set it to use the same one as the axios client. Login using the new proxy IP and then give the cookie to your server.

I’d try changing the user agent/adding any missing headers first though.

Changing the headers did not work in any way that I tried… I may try using a proxy, but I may also try port forwarding if that does not work. Thank you for the suggestion!

Thank you guys so much for the help! Here is what I found:

  • Logging in with captcha is not a good idea unless you know what you are doing.
  • There are multiple alternatives to this, and some a way easier than what I was attempting at first.

I have found a system that works for me, for now of course. So, again, thank you so much for the help!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.