S
SolidJS•4w ago
midnight

Unexpected End of JSON Input on API Route

I am working through creating a OIDC workflow. I have a Astro site that sends the user to the Auth endpoint which handles the handshake with Google for Auth and through the redirect_url I send the browser back to the SolidStart App. I have this file at src/routes/auth/callback.ts that works in dev mode but not when deployed:
import { redirect } from "@solidjs/router";
import type { APIEvent } from "@solidjs/start/server";
import { setCookie } from "vinxi/http";

export async function GET({ request, nativeEvent }: APIEvent) {
const { searchParams } = new URL(request.url);
const code = searchParams.get("code");

if (code) {
const response = await fetch(`${import.meta.env.VITE_AUTH_URL}token`, {
method: "POST",
body: new URLSearchParams({
grant_type: "authorization_code",
client_id: "astro",
code,
redirect_uri: import.meta.env.PROD
? `https://${import.meta.env.VITE_APP_URL}/auth/callback`
: "http://localhost:3000/auth/callback",
}),
});

if (response.ok) {
const { access_token } = await response.json();
setCookie(nativeEvent, "auth_token", access_token, {
httpOnly: import.meta.env.PROD,
maxAge: 60 * 60 * 24 * 7, // 7 days
// sameSite: "strict",
});
return redirect("/");
}
}
return redirect(`https://${import.meta.env.VITE_WWW_URL}`, 406);
}
import { redirect } from "@solidjs/router";
import type { APIEvent } from "@solidjs/start/server";
import { setCookie } from "vinxi/http";

export async function GET({ request, nativeEvent }: APIEvent) {
const { searchParams } = new URL(request.url);
const code = searchParams.get("code");

if (code) {
const response = await fetch(`${import.meta.env.VITE_AUTH_URL}token`, {
method: "POST",
body: new URLSearchParams({
grant_type: "authorization_code",
client_id: "astro",
code,
redirect_uri: import.meta.env.PROD
? `https://${import.meta.env.VITE_APP_URL}/auth/callback`
: "http://localhost:3000/auth/callback",
}),
});

if (response.ok) {
const { access_token } = await response.json();
setCookie(nativeEvent, "auth_token", access_token, {
httpOnly: import.meta.env.PROD,
maxAge: 60 * 60 * 24 * 7, // 7 days
// sameSite: "strict",
});
return redirect("/");
}
}
return redirect(`https://${import.meta.env.VITE_WWW_URL}`, 406);
}
Locally on my machine it works just fine but when deployed I get a 500 Request error Unexpected end of JSON input with the OIDC code in the URL bar: my.domain.com/auth/callback?code=eyJhbGci... If I pull the code out and put it into jwt.io to validate, its valid and expected. I dont know where to go from here to debug further and would love some guidance on where to investigate and understand where my bug is.
18 Replies
Jasmin
Jasmin•4w ago
is the VITE_AUTH_URL env variable set on your deployment?
midnight
midnight•4w ago
It is, I validated by logging it to the console in aws cloudwatch.
Jasmin
Jasmin•4w ago
okay, the errors says that the response doesn't return a json, can you console.log it before calling .json()?
midnight
midnight•4w ago
All the variables seem to be set as expected. I added a console.log statement right below the if (response.ok) so I can see it gets all the way there but it seems to fall over at the const { access_token} = line. Yeah, Are you saying to add a console.log(response) in the if (response.ok) { statement?
Jasmin
Jasmin•4w ago
yes, just above .json()
midnight
midnight•4w ago
Just added it, let me do a deploy since I cant replicate in dev mode
midnight
midnight•4w ago
2024-08-23T15:58:22.972Z 419cfb7f-c87b-436f-9629-9f8302e7d52b INFO LOGGING REPONSE Response {
status: 200,
statusText: 'OK',
headers: Headers {
date: 'Fri, 23 Aug 2024 15:58:22 GMT',
'content-type': 'application/json; charset=UTF-8',
'content-length': '0',
connection: 'keep-alive',
'x-amzn-requestid': '926d3979-c395-427b-b786-560539e80e53',
'x-amzn-trace-id': 'root=1-66c8b19e-4f26f4101c402e915b7ba487;parent=246adf27c28d6bf4;sampled=0;lineage=37c3db30:0'
},
body: ReadableStream { locked: false, state: 'readable', supportsBYOB: true },
bodyUsed: false,
ok: true,
redirected: false,
type: 'basic',
url: 'https://jtizmo3keiw3zxsgiqwkwkxdfm0ldelm.lambda-url.us-east-2.on.aws/token'
}
2024-08-23T15:58:22.972Z 419cfb7f-c87b-436f-9629-9f8302e7d52b INFO LOGGING REPONSE Response {
status: 200,
statusText: 'OK',
headers: Headers {
date: 'Fri, 23 Aug 2024 15:58:22 GMT',
'content-type': 'application/json; charset=UTF-8',
'content-length': '0',
connection: 'keep-alive',
'x-amzn-requestid': '926d3979-c395-427b-b786-560539e80e53',
'x-amzn-trace-id': 'root=1-66c8b19e-4f26f4101c402e915b7ba487;parent=246adf27c28d6bf4;sampled=0;lineage=37c3db30:0'
},
body: ReadableStream { locked: false, state: 'readable', supportsBYOB: true },
bodyUsed: false,
ok: true,
redirected: false,
type: 'basic',
url: 'https://jtizmo3keiw3zxsgiqwkwkxdfm0ldelm.lambda-url.us-east-2.on.aws/token'
}
No description
midnight
midnight•4w ago
I added the "LOGGING RESPONSE` part to make it easier to find in the AWS console.
Jasmin
Jasmin•4w ago
and what is the content of the body when you do response.text()?
midnight
midnight•4w ago
Ill update and deploy. I did get a typescript error that the access_token does not exist on string. Body is unusable: Body has already been read from the web browser and this in aws logs:
2024-08-23T16:12:57.389Z dfc39f63-261c-4b80-811f-e2b3006e2031 INFO LOGGING REPONSE Promise {
<pending>,
[Symbol(async_id_symbol)]: 628,
[Symbol(trigger_async_id_symbol)]: 567,
[Symbol(kResourceStore)]: {
event: H3Event {
__is_event__: true,
node: [Object],
web: [Object],
context: [Object],
_method: 'GET',
_path: '/auth/callback?code=eyJh...redacted...&state',
_headers: Headers {
'cloudfront-is-android-viewer': 'false',
referer: 'https://accounts.google.com/',
'x-amzn-tls-version': 'TLSv1.2',
'cloudfront-viewer-country': 'US',
'sec-fetch-site': 'cross-site',
2024-08-23T16:12:57.389Z dfc39f63-261c-4b80-811f-e2b3006e2031 INFO LOGGING REPONSE Promise {
<pending>,
[Symbol(async_id_symbol)]: 628,
[Symbol(trigger_async_id_symbol)]: 567,
[Symbol(kResourceStore)]: {
event: H3Event {
__is_event__: true,
node: [Object],
web: [Object],
context: [Object],
_method: 'GET',
_path: '/auth/callback?code=eyJh...redacted...&state',
_headers: Headers {
'cloudfront-is-android-viewer': 'false',
referer: 'https://accounts.google.com/',
'x-amzn-tls-version': 'TLSv1.2',
'cloudfront-viewer-country': 'US',
'sec-fetch-site': 'cross-site',
I need to edit this later to remove my info
Jasmin
Jasmin•4w ago
:thinkies: response.text() shouldn't return this error you need to await response.text() afaik and then you can see the plain response which isn't a json it seems you can ignore the other error at the bottom, that's because you call text() and json() and both want to consume the body
midnight
midnight•4w ago
Yeah, seems like it returns a jwt encoded response for the code. I think the problem I am trying to understand is why does this work when running locally on my machine. Let me check something locally though
midnight
midnight•4w ago
Yeah, running in dev mode, the original code works and sets the auth_token to
...redacted...
...redacted...
No description
Jasmin
Jasmin•4w ago
please watch out sharing your tokens like this xD I don't know what could be the cause of this bth
midnight
midnight•4w ago
Theres nothing sensitive 😅 just an email address
Want results from more Discord servers?
Add your server