Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing Cookies #2

Closed
jamcalli opened this issue Nov 2, 2024 · 18 comments
Closed

Passing Cookies #2

jamcalli opened this issue Nov 2, 2024 · 18 comments

Comments

@jamcalli
Copy link

jamcalli commented Nov 2, 2024

Great package.

Working very well.

I have a question though. How do you set cookies from localhost in production? I have been banging my head against this for a while so thought I would see if you knew the solution.

Cheers.

@kirill-konshin
Copy link
Owner

Cookies are just headers, library passes them through, so should work out of the box. If not, check if you see set-cookie header in response in devtools. And make sure you use Nextjs cookie helper on server side to set them on response. I think the simplest way would be to do it in API handler (aka API route).

Let me know what you will see there.

@jamcalli
Copy link
Author

jamcalli commented Nov 2, 2024

I've been trying to do exactly that.

Works fine in dev, but as soon as launching a built app the cookies do not get passed.

Can you confirm it works for you?

@jamcalli
Copy link
Author

jamcalli commented Nov 4, 2024

I managed to trace the issue back to the partition not working when using the interceptor and thus no persistent session.

http://localhost:3000/ with error: ERR_CONNECTION_REFUSED

When setting the window to have partition:

mainWindow = new BrowserWindow({
    width: 2000,
    height: 800,
    webPreferences: {
        contextIsolation: true,
        devTools: true,
        partition: PARTITION_NAME,

    },
}); 

@kirill-konshin
Copy link
Owner

@jamcalli I have researched the problem and looks like Electron simply ignores cookies in the interceptor. Some bugs for reference: electron/electron#30717 and electron/electron#39525.

So I have reimplemented the intercept using non-deprecated protocol.handle and added cookie support 0.2.0 release: https://github.com/kirill-konshin/next-electron-rsc/releases/tag/0.2.0

Make sure to check out readme as API has changed, you now need to provide session to createInterceptor.

@jamcalli
Copy link
Author

jamcalli commented Nov 4, 2024

@kirill-konshin thanks for looking into this.

The cookies still do not work though, and now I am getting crashes every time I try and interact with cookies.

For example, one of my components stores states in a cookie, and I get the following error:

[ELECTRON] [NEXT] Error TypeError: argument name is invalid: sidebar:state
[ELECTRON]     at serialize (\node_modules\next-electron-rsc\node_modules\cookie\dist\index.js:132:15)
[ELECTRON]     at <unknown> (\node_modules\next-electron-rsc\build\index.js:60:59)
[ELECTRON]     at Generator.next (<anonymous>)
[ELECTRON]     at fulfilled (\node_modules\next-electron-rsc\build\index.js:5:58)

My component sets a cookie like so:

const SIDEBAR_COOKIE_NAME = "sidebar:state"
document.cookie = `${SIDEBAR_COOKIE_NAME}=${open}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`

I also use the interceptor in dev mode where electron will allow localhost and partitions (to test cross-process functionality), and with the partition set, everything works as expected with the previous version. Something to do with localhost, instead of the typical File:// when running in production causes the error:

http://localhost:3000/ with error: ERR_CONNECTION_REFUSED

If I set the window to launch the standalone/index.html, the partition works, but it throws off all the pathing within the interceptor.

@kirill-konshin
Copy link
Owner

The dev mode simply assumes you run Next.js as a server, in the usual way, so things work as expected. For production mode, there is no server running, and no ports are open.

In prod mode library does some magic to convert cookies from Electron cookie storage to Next.js and back.

sidebar:state is not a valid cookie name according to NPM cookie package: https://github.com/jshttp/cookie/blob/master/src/index.ts#L251, besides a colon (:) is not a valid character in an HTTP cookie name. According to the RFC 6265 specification, cookie names must follow the rules for “token” characters:

•	Alphanumeric characters (A-Z, a-z, 0-9)
•	Certain special characters: ! # $ % & ' * + - . ^ _  | ~`

Using invalid characters, like a colon, can cause cookies to be ignored or lead to errors in some HTTP clients and servers.

Browsers tend to be forgiving with certain non-standard or invalid characters in cookie names, including colons, as part of a broader principle of “robustness” in web technologies.

So just use dashes, maybe?

@jamcalli
Copy link
Author

jamcalli commented Nov 5, 2024

That's all fair and true.

I am just using the unmodified shadcn dashboard component to test, where that cookie is set.

I would assume that the package should work with those components, given their popularity.

Perhaps a regex to for compliance?

@kirill-konshin
Copy link
Owner

Well the regex in cookie library is compliant with RFC, and this lib is used in Next.js itself, Express, and so on. Some Java-based servers ignore such names... so technically, Shadcn should not have a name like this. You can try to bring their attention to it.

On the other hand tomorrow I will try to find a more relaxed way (for instance, downgrade to 0.6.0). There's a ticket in cookie library: jshttp/cookie#191, I commented there.

kirill-konshin added a commit that referenced this issue Nov 5, 2024
@kirill-konshin
Copy link
Owner

I have downgraded the cookie lib to 0.6.0 to unblock you for now. Let's see what they will suggest. New version was released: 0.2.1

@jamcalli
Copy link
Author

jamcalli commented Nov 5, 2024

I can confirm that everything is working more or less as I would expect.

Really appreciate your commitment to making this work.

The cookies show when explicitly set in the response, and the partition issues related to the session are also resolved.

I like to control routing using cookies from iron-session, in conjunction with middleware, and they are still not being set.

For example:

        import { cookies } from 'next/headers';
        import { getIronSession } from 'iron-session';

        const session = await getIronSession<SessionData>(cookies(), sessionOptions);
        await session.save();

Does not result in any cookies being set.

A small caveat that will be completely circumvented when next middleware can run in a node runtime.

Cheers and thanks again.

@kirill-konshin
Copy link
Owner

kirill-konshin commented Nov 5, 2024

I have tried this lib, and works as expected. Few corrections though: in Next.js 15 you need to await cookies(). Also make sure you rebuild your Next.js app before you build Electron.

    const session = await getIronSession(await cookies(), { password, cookieName: 'iron' });
    session['username'] = 'Alison';
    await session.save();

I've created a ticket for them: vvo/iron-session#869

I can see cookies being set in Electron's storage, and upon next reload I see them in Next.js Route Handler. Keep in mind that Iron cookie is httpOnly, so you won't see it in frontend.

@kirill-konshin
Copy link
Owner

I have published 0.2.2 just in case to fix potential race condition in the lib.

@jamcalli
Copy link
Author

jamcalli commented Nov 6, 2024

I can confirm everything is working exactly as expected.

Thanks so much.

@kirill-konshin
Copy link
Owner

Perfect, thanks for reporting! It’s impossible to predict all potential use cases, so your feedback is extremely valuable.

@jamcalli
Copy link
Author

jamcalli commented Nov 6, 2024

One final unrelated question. Do you know if you configure next image cache optimization directory?

Asar is read only and ideally I would set the cache to the user Data dir but I'm not sure that's possible.

Or is asar not recommended?

@kirill-konshin
Copy link
Owner

Please create a separate issue for this and I will think on it. Should be doable. ASAR is recommended, but not required.

@kirill-konshin
Copy link
Owner

@jamcalli I have explored a bit, here's the new ticket for cache dir: #3

@kirill-konshin
Copy link
Owner

jshttp/cookie#191 version 1.0.2 has been released with relaxed set of cookie-related checks. It works properly now, I have published 0.2.3 with this change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants