I'm not sure if this bug is caused by Appwrite or Next.js. Here I've described the full scenario in detail.
Any help will be appreciated
#Is it Next.js or Appwrite?
1 messages · Page 1 of 1 (latest)
after following the stacktrace, I noticed that Appwrite uses the isomorphic-form-data library that's using the window object in their lib/browser.js file.
- Is there any way to get rid of this?
- Does anyone have any idea why this library is important for Appwrite to use?
What happened is that the isomorphic-form-data load the browser file and not the main one.
- You can customize the package but it ain't maintainable
- It creates the form-data for when you're uploading files
To solve that can you share your packages.json
Are you using vite?
Sounds like it's giving isomorphism behavior to Appwrite form data when working with multipart form. But as the middleware.ts file runs server-side, shouldn't it load the index.js file instead of browser.js?
should i dm u? or send it here?
nope
Responded
If you can go with Steven's suggestions.
If not you can customize the package file itself to load the main module
You suggested not using the web sdk in the middleware. what can be the workaround then as I need to check for the user logged-in status in the middleware? Hit /v1/account manually?
package file of isomorphic-form-data lib?
The appwrite one, change it to load isomorphic-form-data main module, change it to:
-import 'isomorphic-form-data';
+import 'isomorphic-form-data/lib';
Or
-import 'isomorphic-form-data';
+global.FormData = module.exports = require('form-data')
Both should work, but in this case you'll need to redeploy custom-version of the appwrite package.
What I have done in nextjs is:
- create the session in the client side (I'm using OAuth2 but should work with any auth method)
- In the success call I store the user info in a new cookie (this solves third party cookies problems)
- I read the new cookie in the middleware
i tried both. but it's still loading the browser.js file
can you please show me the lines where you read the cookies in the middleware file and redirect the user based on that?
Sure!, the middleware looks like this:
export const middleware = async (req: NextRequest) => {
let user: Models.User<UserPreferences> | null = null;
const userSession = req.cookies.get("userSession")?.value;
try {
user = JSON.parse(userSession || "");
} catch {}
if (!user && !req.url.endsWith("/login") && !req.url.endsWith("/success")) {
return NextResponse.redirect(`${process.env.NEXT_PUBLIC_FRONTEND_URL}/login`);
}
return NextResponse.next();
};
export const config = {
matcher: ["/((?!failure|auth|_next/static|_next/image|favicon.ico|.*\\..*).*)"],
};
this doesn't actually validate the session though 🧐
Oh I forgot to mention, in my case the cookie have a short time, that is why I don't validate it, at the moment if the session isn't valid, appwrite just return the corresponding error
Correct me if I'm wrong. Your code checks if there's a cookie with the name userSession exists, and redirects the user based on that. Isn't it?
Yes in this case, I just read the user object stored in the cookie and the redirect where I need to, I don't make many validations here (is planed to improve this in the future though) because if the session isn't valid, appwrite throws an error, I catch the error and it makes to remove the cookie
You can improve this, I use this method to avoid calls to appwrite, and because ssr was hard to implement
Your scenario might be different, but as Steven said, it ain't validating the session. i also followed the same approach at the beginning, then realized it only checks if the cookie exists. This means the user can easily create the cookie from the browser console manually to enter any protected route
But if the appwrite cookie isn't created, the sdk will return (role: xxxx) missing scope (xxxx)
I catch error, and delete the cookie, so the middleware redirect to login again
@twin matrix
I keep relying on appwrite validation
ofcourse it would be better to make that validation on the server, but I couldn't make it work at that moment, and this was my workaround
The user can create a cookie, however that cookie won't be valid for the backend, just for the frontend. It won't make an appwrite call valid
How should we validate whether the session is valid? Is there a REST endpoint that makes this doable?