K
Kinde4w ago
readme

Invalid Token Error

In my next.js application i am using next server actions for my api routes protected my kinde. I have mainly 4 routes get, get/id, edit and delete. All the routes work fine except the edit one where it gives me this error:
getUser Error [InvalidTokenError]
at eval (webpack-internal:///(rsc)/./node_modules/jwt-decode/build/jwt-decode.esm.js:6:1134)
at (rsc)/./node_modules/jwt-decode/build/jwt-decode.esm.js (C:\Users\harka\OneDrive\Documents\coding\paperless\.next\server\vendor-chunks\jwt-decode.js:40:1)
at __webpack_require__ (C:\Users\harka\OneDrive\Documents\coding\paperless\.next\server\webpack-runtime.js:33:42)
at eval (webpack-internal:///(rsc)/./node_modules/@kinde-oss/kinde-auth-nextjs/dist/server/index.js:15:68)
at (rsc)/./node_modules/@kinde-oss/kinde-auth-nextjs/dist/server/index.js (C:\Users\harka\OneDrive\Documents\coding\paperless\.next\server\vendor-chunks\@kinde-oss.js:40:1)
at __webpack_require__ (C:\Users\harka\OneDrive\Documents\coding\paperless\.next\server\webpack-runtime.js:33:42)
at eval (webpack-internal:///(rsc)/./src/app/layout.js:13:93)
at (rsc)/./src/app/layout.js (C:\Users\harka\OneDrive\Documents\coding\paperless\.next\server\app\receipts\[id]\page.js:489:1)
at Function.__webpack_require__ (C:\Users\harka\OneDrive\Documents\coding\paperless\.next\server\webpack-runtime.js:33:42)
at async e9 (C:\Users\harka\OneDrive\Documents\coding\paperless\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:396491)
at async rU (C:\Users\harka\OneDrive\Documents\coding\paperless\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:39:7365)
at async r2 (C:\Users\harka\OneDrive\Documents\coding\paperless\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:39:17560) {
message: 'Invalid token specified'
}
POST /api/receipts/edit/info/8r5WW52G455NpnRyW500 307 in 67ms
POST /api/auth/login 405 in 16ms
getUser Error [InvalidTokenError]
at eval (webpack-internal:///(rsc)/./node_modules/jwt-decode/build/jwt-decode.esm.js:6:1134)
at (rsc)/./node_modules/jwt-decode/build/jwt-decode.esm.js (C:\Users\harka\OneDrive\Documents\coding\paperless\.next\server\vendor-chunks\jwt-decode.js:40:1)
at __webpack_require__ (C:\Users\harka\OneDrive\Documents\coding\paperless\.next\server\webpack-runtime.js:33:42)
at eval (webpack-internal:///(rsc)/./node_modules/@kinde-oss/kinde-auth-nextjs/dist/server/index.js:15:68)
at (rsc)/./node_modules/@kinde-oss/kinde-auth-nextjs/dist/server/index.js (C:\Users\harka\OneDrive\Documents\coding\paperless\.next\server\vendor-chunks\@kinde-oss.js:40:1)
at __webpack_require__ (C:\Users\harka\OneDrive\Documents\coding\paperless\.next\server\webpack-runtime.js:33:42)
at eval (webpack-internal:///(rsc)/./src/app/layout.js:13:93)
at (rsc)/./src/app/layout.js (C:\Users\harka\OneDrive\Documents\coding\paperless\.next\server\app\receipts\[id]\page.js:489:1)
at Function.__webpack_require__ (C:\Users\harka\OneDrive\Documents\coding\paperless\.next\server\webpack-runtime.js:33:42)
at async e9 (C:\Users\harka\OneDrive\Documents\coding\paperless\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:35:396491)
at async rU (C:\Users\harka\OneDrive\Documents\coding\paperless\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:39:7365)
at async r2 (C:\Users\harka\OneDrive\Documents\coding\paperless\node_modules\next\dist\compiled\next-server\app-page.runtime.dev.js:39:17560) {
message: 'Invalid token specified'
}
POST /api/receipts/edit/info/8r5WW52G455NpnRyW500 307 in 67ms
POST /api/auth/login 405 in 16ms
Note that my kinde debug mode is set to true.
10 Replies
readme
readmeOP4w ago
Just to give an idea of my code and workflow im attaching the code Modal.jsx worker method
const handleSubmitEditPayment = async (e) => {
e.preventDefault();
const formData = new FormData(e.target);

formData.append("paymentInfo.method", method);
formData.append("paymentInfo.status", status);

await sendUpdateReceipt(id, formData)
.then((result) => console.log(result))
.catch((error) => console.log(error));
};
const handleSubmitEditPayment = async (e) => {
e.preventDefault();
const formData = new FormData(e.target);

formData.append("paymentInfo.method", method);
formData.append("paymentInfo.status", status);

await sendUpdateReceipt(id, formData)
.then((result) => console.log(result))
.catch((error) => console.log(error));
};
sendUpdateReceipt.js
"use server";

import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server";

export const sendUpdateReceipt = async (id, formData) => {
try {
const { getAccessTokenRaw } = getKindeServerSession();
const token = await getAccessTokenRaw();

const data = {};
formData.forEach((value, key) => {
data[key] = value;
});

const response = await fetch(`http://localhost:3000/api/receipts/edit/${id}`, {
method: "POST",
headers: {
"x-kinde-token": token,
"Content-Type": "application/json"
},
body: JSON.stringify(data),
});

if (response.ok) {
const result = await response.json();
return result;
} else {
const errorResult = await response.json();
return { error: errorResult.error };
}
} catch (error) {
return {
error,
};
}
};
"use server";

import { getKindeServerSession } from "@kinde-oss/kinde-auth-nextjs/server";

export const sendUpdateReceipt = async (id, formData) => {
try {
const { getAccessTokenRaw } = getKindeServerSession();
const token = await getAccessTokenRaw();

const data = {};
formData.forEach((value, key) => {
data[key] = value;
});

const response = await fetch(`http://localhost:3000/api/receipts/edit/${id}`, {
method: "POST",
headers: {
"x-kinde-token": token,
"Content-Type": "application/json"
},
body: JSON.stringify(data),
});

if (response.ok) {
const result = await response.json();
return result;
} else {
const errorResult = await response.json();
return { error: errorResult.error };
}
} catch (error) {
return {
error,
};
}
};
middleware.js
import { NextResponse } from "next/server";
import { decode } from "jsonwebtoken";

export default async function middleware(req) {
const token = req.headers.get("x-kinde-token");

if (!token) {
return NextResponse.json({ error: "No Token provided" }, { status: 401 });
}

const { header } = decode(token, { complete: true });

const headersExist = header && Object.keys(header).length !== 0;

if (!headersExist) {
return NextResponse.json({ error: "Incorrect Token Provided" }, { status: 401 });
}

const requestHeaders = new Headers(req.headers);
requestHeaders.set('x-kinde-header', JSON.stringify(header));
requestHeaders.set('x-kinde-token', token);

const response = NextResponse.next({
request: {
headers: requestHeaders,
},
});

return response;
}

export const config = {
matcher: ["/api/receipts/:path*"],
};
import { NextResponse } from "next/server";
import { decode } from "jsonwebtoken";

export default async function middleware(req) {
const token = req.headers.get("x-kinde-token");

if (!token) {
return NextResponse.json({ error: "No Token provided" }, { status: 401 });
}

const { header } = decode(token, { complete: true });

const headersExist = header && Object.keys(header).length !== 0;

if (!headersExist) {
return NextResponse.json({ error: "Incorrect Token Provided" }, { status: 401 });
}

const requestHeaders = new Headers(req.headers);
requestHeaders.set('x-kinde-header', JSON.stringify(header));
requestHeaders.set('x-kinde-token', token);

const response = NextResponse.next({
request: {
headers: requestHeaders,
},
});

return response;
}

export const config = {
matcher: ["/api/receipts/:path*"],
};
/api/receipts/edit/[id]/route.js
import { db } from "@/config/firebase";
import { getReceipt } from "@/helpers/getReceipt";
import { NextResponse } from "next/server";

export const POST = async (req, { params }) => {
try {

const data = await req.json();
const receiptId = params.id;
const receiptRef = db.collection("receipts").doc(receiptId);
await receiptRef.update(data);

const updatedReceipt = await getReceipt(receiptId)

return NextResponse.json(
{
message: "Receipt updated successfully",
receipt: updatedReceipt,
},
{ status: 200 }
);
} catch (error) {
console.log(error);
return NextResponse.json(
{
error: "Error updating image",
},
{ status: 400 }
);
}
};

import { db } from "@/config/firebase";
import { getReceipt } from "@/helpers/getReceipt";
import { NextResponse } from "next/server";

export const POST = async (req, { params }) => {
try {

const data = await req.json();
const receiptId = params.id;
const receiptRef = db.collection("receipts").doc(receiptId);
await receiptRef.update(data);

const updatedReceipt = await getReceipt(receiptId)

return NextResponse.json(
{
message: "Receipt updated successfully",
receipt: updatedReceipt,
},
{ status: 200 }
);
} catch (error) {
console.log(error);
return NextResponse.json(
{
error: "Error updating image",
},
{ status: 400 }
);
}
};

TotalScrub
TotalScrub4w ago
I'm not familiar with Next.js sorry. But have you checked in DevTools that your app is sending across the exact same header for the edit requests as it is for the other requests? I don't believe Kinde is going to care what type of web method is called unless you're using API scopes.
readme
readmeOP4w ago
Yes I am sending the exact same header for the edit requests. I’ve named it x-kinde-token . Even when I log the token in the middleware the token and tye resultant decoded header both get logged. And after the middleware I don’t really have a auth check for this route. So idk where is this extra getUser check being made and instead of a 200 I get a 405 method not allowed
Ages
Ages4w ago
Hi @readme , Thank you for providing the detailed context and code. I wanted to check in first—are you still facing the issue with the Invalid Token Error on the edit route? If yes, here are a few clarifications and suggestions to help us troubleshoot further: 405 Method Not Allowed: This indicates the HTTP method (POST) might not be recognized for the endpoint /api/auth/login. Could this request be redirecting incorrectly? If possible, log the request URL and headers on both client and server sides to confirm. Token Decoding Issue: Since you mentioned the token is logged successfully in middleware, the error could arise in subsequent steps (like token verification or backend usage). Have you verified if the token is valid at the exact point it’s passed to /api/receipts/edit/[id]? Middleware Token Validation: Could you confirm if the middleware is applying any additional restrictions (like roles or scopes) for the edit route that may differ from get, delete, etc.? Kinde Debug Logs: Since debug: true is enabled, any additional logs from Kinde’s SDK might give hints on where the invalid token check is happening. Let me know if you need further assistance—I’d be happy to dig deeper
readme
readmeOP4w ago
Yes i'm still facing that same issue. I also updated my next js to version 15. after logging the headers I am seeing the token and the headers begin logged. I am attaching the logged result.
import { NextResponse } from "next/server";
import { decode } from "jsonwebtoken";

export default async function middleware(req) {
const token = req.headers.get("x-kinde-token");

if (!token) {
return NextResponse.json({ error: "No Token provided" }, { status: 401 });
}

const { header } = decode(token, { complete: true });
if (!header) {
return NextResponse.json({ error: "Invalid Token" }, { status: 401 });
}

// No redirects, just forward headers
const requestHeaders = new Headers(req.headers);
requestHeaders.set("x-kinde-header", JSON.stringify(header));
requestHeaders.set("x-kinde-token", token);

console.log(requestHeaders)

return NextResponse.next({ request: { headers: requestHeaders } });
}


export const config = {
matcher: ["/api/receipts/:path*"],
};
import { NextResponse } from "next/server";
import { decode } from "jsonwebtoken";

export default async function middleware(req) {
const token = req.headers.get("x-kinde-token");

if (!token) {
return NextResponse.json({ error: "No Token provided" }, { status: 401 });
}

const { header } = decode(token, { complete: true });
if (!header) {
return NextResponse.json({ error: "Invalid Token" }, { status: 401 });
}

// No redirects, just forward headers
const requestHeaders = new Headers(req.headers);
requestHeaders.set("x-kinde-header", JSON.stringify(header));
requestHeaders.set("x-kinde-token", token);

console.log(requestHeaders)

return NextResponse.next({ request: { headers: requestHeaders } });
}


export const config = {
matcher: ["/api/receipts/:path*"],
};
No description
readme
readmeOP4w ago
i do not have any token verification configured for this route after the middleware stage. Also after updating as you can see the message has changed to getUser [TypeError: Cannot read properties of null (reading 'sub')]. Which could mean that the wherever this additiional step is taking place it is returing null after decoding the token. after the middleware i directly have my route.js
import { db } from "@/config/firebase";
import { getReceipt } from "@/helpers/getReceipt";
import { NextResponse } from "next/server";

export const PUT = async (req, { params }) => {
try {
console.log(req)
const data = await req.json();
const receiptId = params.id;
const receiptRef = db.collection("receipts").doc(receiptId);
await receiptRef.update(data);

const updatedReceipt = await getReceipt(receiptId)

return NextResponse.json(
{
message: "Receipt updated successfully",
receipt: updatedReceipt,
},
{ status: 200 }
);
} catch (error) {
console.log(error);
return NextResponse.json(
{
error: "Error updating image",
},
{ status: 400 }
);
}
};

import { db } from "@/config/firebase";
import { getReceipt } from "@/helpers/getReceipt";
import { NextResponse } from "next/server";

export const PUT = async (req, { params }) => {
try {
console.log(req)
const data = await req.json();
const receiptId = params.id;
const receiptRef = db.collection("receipts").doc(receiptId);
await receiptRef.update(data);

const updatedReceipt = await getReceipt(receiptId)

return NextResponse.json(
{
message: "Receipt updated successfully",
receipt: updatedReceipt,
},
{ status: 200 }
);
} catch (error) {
console.log(error);
return NextResponse.json(
{
error: "Error updating image",
},
{ status: 400 }
);
}
};

i have also verified that the token is valid by copy pasting my token to the kinde jwt decoder website.
readme
readmeOP4w ago
No description
readme
readmeOP4w ago
i've likely found the issue. after building the application using command npm run build i noticed that the /api/receipts/edit/[id] folder is not being included in the build. This could be the reason. What do you think?
No description
readme
readmeOP4w ago
nvm i found the error @Ages @TotalScrub I named my file route..js instead of route.js. You can close this thread now. Thank you for your help.
Ages
Ages4w ago
Hi @readme , I'm glad to hear the issue has been resolved! If there's anything else you'd like assistance with or any additional details you'd like to discuss, please don't hesitate to reach out. If this resolves your query for now, we'll consider this matter closed. Looking forward to your response! Thank you, Ages
Want results from more Discord servers?
Add your server