HTTP 403 (Forbiden)

so i want to make a server list for another place
but it shows the error

local RS = game:GetService("ReplicatedStorage")
local HttpService = game:GetService("HttpService")

local GSRemote =  RS:WaitForChild("Remotes"):WaitForChild("GetServers")

function getServerList(placeId)
	local cursor
	local servers = {}
	repeat
		local response = HttpService:JSONDecode(HttpService:GetAsync("https://games.roproxy.com/v1/games/" .. placeId .. "/servers/Public?sortOrder=Asc&limit=100" .. (cursor and "&cursor=" .. cursor or "")))
		for _, v in pairs(response.data) do
			table.insert(servers, v)
		end
		cursor = response.nextPageCursor
	until not cursor
	return servers
end

GSRemote.OnServerEvent:Connect(function(plr, id)
	local list = getServerList(id)
	GSRemote:FireClient(plr, list)
end)

Error 403 means you do not have access to the resource at the link provided. Last time I checked the v1 games api requires an x-csrf-token.

Easy way to do this securely:

  1. Create a new Secret on your game equal to your .ROBLOSECURITY Cookie (You need HTTPServices enabled for this, but I’m assuming you already do).
  2. Create an API GET request to https://auth.roproxy.com/v2/logout with a Header containing your cookie and grab the x-csrf-token as a header
  3. Pass that token to the games API for access

Here’s a code mockup on how to do this:

local HttpService = game:GetService("HttpService")

local function GetToken()
	local Secret = HttpService:GetSecret("SecretName")
	local Success, Response = pcall(function()
		return HttpService:RequestAsync({
			Url = "https://auth.roproxy.com/v2/logout",
			Method = "GET",
			Headers = {
				["Content-Type"] = "application/json",
				["Cookie"] =  Secret:AddPrefix(".ROBLOSECURITY=")
			}
		})
	end)
	if Success and Response then
		return Response.Headers["x-csrf-token"]
	else
		warn(Response)
		return nil
	end
end

local token =  GetToken()
if token ~= nil then
	--your HttpService GetAsync request here, but add the header ["x-csrf-token"] = token
end

Please lmk if you have any more questions regarding this, I’m happy to help.

thanks for answer, i’ll try that with another cookie from a brand new account cuz yk not safe to put the real one on a game that can be stealed if i do not put enough attention

Using your account cookie as a Roblox Secrets is encrypted and Secure. This is a fairly recent feature, but it allows you to store things like API keys, and access codes in a manner that its not accessible besides what the API request it’s used in returns.

nvm i got what you were saying

Actually, you might want to do that still. I don’t know how safe roproxy.com is with its mirrors or if anything is tracked. If it’s open-source I might do a deepdive later, but generally I set up my own local APIs for anything I would use something like that for.

1 Like

i can’t host so i use that, i’ll put the fake one still thanks a lot

I just use localhost:3000, usually using express.js for setting up any servers and endpoints I need.

i can’t let my pc always ON so i can’t (assuming i need to let it on)

Nah you don’t always need to have it always on. I just run the local server whenever I need to access information like that. I can provide a basic skeleton for doing that if you’d like. You wouldn’t be able to access it from a live game instance, but it works for Studio because that is also local.

yeah but do i need to if i want my game to be played anytime ?

Yeah, to have this as a live feature in-game you would need to do it via script like you are currently doing with the added stuff. That being said it can be helpful to debug with a local server like this.

1 Like

i did this

local RS = game:GetService("ReplicatedStorage")
local HttpService = game:GetService("HttpService")

local GSRemote = RS:WaitForChild("Remotes"):WaitForChild("GetServers")


local function GetToken()
	local Secret = HttpService:GetSecret("DWICHANGEDTHENAME")
	local Success, Response = pcall(function()
		return HttpService:RequestAsync({
			Url = "https://auth.roproxy.com/v2/logout",
			Method = "GET",
			Headers = {
				["Content-Type"] = "application/json",
				["Cookie"] = Secret:AddPrefix(".ROBLOSECURITY=")
			}
		})
	end)

	if Success and Response then
		return Response.Headers["x-csrf-token"]
	else
		warn(Response)
		return nil
	end
end

local function GetServerList(placeId, token)
	local cursor
	local servers = {}
	repeat
		local Success, Response = pcall(function()
			return HttpService:RequestAsync({
				Url = "https://games.roproxy.com/v1/games/" .. placeId .. "/servers/Public?sortOrder=Asc&limit=100" .. (cursor and "&cursor=" .. cursor or ""),
				Method = "GET",
				Headers = {
					["x-csrf-token"] = token,
					["Content-Type"] = "application/json"
				}
			})
		end)

		if Success and Response then
			local responseData = HttpService:JSONDecode(Response.Body)
			for _, v in pairs(responseData.data) do
				table.insert(servers, v)
			end
			cursor = responseData.nextPageCursor
		else
			warn("Failed to fetch server list:", Response)
			break
		end
	until not cursor

	return servers
end

GSRemote.OnServerEvent:Connect(function(plr, placeId)
	local token = GetToken()
	if token then
		local serverList = GetServerList(placeId, token)
		GSRemote:FireClient(plr, serverList)
	else
		warn("Failed to get x-csrf-token")
		GSRemote:FireClient(plr, { error = "Failed to fetch token" })
	end
end)

still got some problems to fix

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