appwrite-ssr-next-js icon indicating copy to clipboard operation
appwrite-ssr-next-js copied to clipboard

How to make it work on localhost

Open vincaslt opened this issue 2 years ago • 12 comments

So it seems that to make SSR work we need to make appwrite API a subdomain of our SSR server. I made it work, but it's only for hosted websites. Is there a way to make it work locally while developing? In that case the cookie domain for SSR is going to be localhost, which will not work with the appwrite cloud. Should I be setting up some sort of proxy?

vincaslt avatar May 27 '23 14:05 vincaslt

Yes, a proxy can help here. Another solution could be to edit /etc/hosts and add definition for appwrite.localhost to point to Appwrite Cloud.

Finally, having a local instance of Appwrite can help too. There might also be some browsers for developers that allow such insecure cookies, but I haven't tired that.

Meldiron avatar May 28 '23 09:05 Meldiron

Any other solution to this?

ghost avatar May 28 '23 10:05 ghost

I don't want to have to install locally.

ghost avatar May 28 '23 10:05 ghost

But wait, what's the main reason for having to make the appwrite server a subdomain of the SSR server? Isn't it to make sure that browsers send the cookies to appwrite's servers when calling the appwrite APIs from the client? When the login request is proxied, we're essentially only rewriting the set-cookie header so that the browser sends it to both the SSR server, and the appwrite server when used directly on the client (provided the appwrite server is on a subdomain).

If we're not using appwrite directly on the client, is there still a need to make the appwrite server on a subdomain of the SSR host?

Also, since the web client sdk send X-Fallback-Cookies read from localStorage, could a potential solution to this be to manually add the X-Fallback-Cookies storage item to localStorage after redirecting back to the client from the proxy API? This way, the web sdk when used on the client will read it and use it when making requests.

Will that work?

ghost avatar May 28 '23 10:05 ghost

This would mean that on localhost, the session will be stored in storage, and in production, it'll use the cookies... Something like that

ghost avatar May 28 '23 10:05 ghost

Based on the following line: https://github.com/appwrite/sdk-for-web/blob/7b37a2bec1dbe47b55e2c962996046f56b763192/src/client.ts#L426

It looks like the web client writes to the cookieFallback localStorage item whenever it's used to make a request, and the request returns a valid X-Fallback-Cookie header. If you look some live above that (374), it reads the item, sets it to the X-Fallback-cookies header and sends it along with other headers when used to make a request. So, if we can write that item to Storage, using Appwrite on the Client will also work, hopefully. What do you think?

ghost avatar May 28 '23 10:05 ghost

Also @Meldiron, I'll like to know why you had include the Auth cookies in an object and then use JSON.stringify on it before setting it on the client here:

https://github.com/Meldiron/appwrite-ssr-next-js/blob/32cbcd586be3d63423d8bfc7a3a7e958dad00eba/src/app/AppwriteService.ts#L29-L31

ghost avatar May 28 '23 21:05 ghost

I managed to get it to work using proxy, although it's a bit clunky. I hadn't realized that hosting locally was an option, though now it seems obvious :D Hosting the backend locally is fine for me for development.

vincaslt avatar May 29 '23 10:05 vincaslt

Can you share some details of what you implemented?

ghost avatar May 29 '23 10:05 ghost

I've not yet implemented SSR using the technique in this repo, but I will be doing that, and that's why I'm following this. I'm just curious, @vincaslt what exactly was the error you ran into when trying to get it to work on localhost?

ghost avatar May 31 '23 15:05 ghost

Local Appwrite Instance

So if you have a local instance of NextJS AND Appwrite, all you need to do is update:

https://github.com/Meldiron/appwrite-ssr-next-js/blob/32cbcd586be3d63423d8bfc7a3a7e958dad00eba/src/app/AppwriteService.ts#L3-L7

to:

export const SsrHostname: string = "localhost";
export const AppwriteHostname: string = "localhost";

export const AppwriteEndpoint =
  "http://localhost/v1";

Appwrite Cloud

If you have a local instance of NextJS and are connecting to Appwrite Cloud, connecting will be trickier because of browsers will block cookies from an HTTP page going to an HTTPS server. To get around this, you'll need to put a HTTPS proxy in front of your app (as well as all the other hostname configurations:

  1. update your hosts file to add:
127.0.0.1 example.com
157.230.79.70 appwrite.example.com # assuming cloud.appwrite.io still points to 157.230.79.70
  1. update the following:

https://github.com/Meldiron/appwrite-ssr-next-js/blob/32cbcd586be3d63423d8bfc7a3a7e958dad00eba/src/app/AppwriteService.ts#L3-L7

to:

export const SsrHostname: string = 'example.com';
export const AppwriteHostname: string = "appwrite.example.com";

export const AppwriteEndpoint =
  "https://appwrite.example.com/v1";
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0";
  1. start up nextjs (npm run dev)
  2. start an HTTPS proxy (npx local-ssl-proxy --source 3001 --target 3000 assuming NextJS is running on port 3000)
  3. open a browser
  4. browse to https://appwrite.example.com and proceed to the page to accept the self-signed certificate warning
  5. browse to https://example.com:3001 (assuming you set the HTTPS source port to 3001) and proceed to the page to accept the self-signed certificate warning

stnguyen90 avatar Jun 13 '23 16:06 stnguyen90

Thanks for this. I actually tried some things too very similar to what you shared. I first updated my hosts file and set appwrite to subdomain appwrite.myapp.local pointing to an an appwrite cloud IP, but then I figured out that they have load balancing in place and that won't always work.

I then decided to settle for a local DNS server that would allow me set up cname records so I won't be affected by appwrite cloud's load balancing. I settled for technitium DNS server which does a really good job.

The last thing that was left to figure out though was the SSL thing. I got hit by 500 internal server error whenever I tried to access appwrite cloud from the domain I had configured. It turns out that I had to have SSL enabled, but I was running out of time, so I didn't bother anymore, and decided to switch to client side rendering.

Anyways, thanks for sharing.

ghost avatar Jun 14 '23 06:06 ghost