Hacker News new | ask | show | jobs
by ajbeach22 2400 days ago
I've seen lots of tutorials for single page apps/api architectures that specifically store JWT in localstorage, it's endemic.

What I haven't seen though, is guidance on how to deploy SPA web apps using cookies properly (with either jwt or session token in http only cookies)

From what I have found, there are only a few options:

1. host api at 'api.mydomain.com' and frontend from 'mydomain.com'. You will have to deal with CORS and options requests which can add significant latency for non-simple CORS requests. Not to mention extra configuration with CORS headers.

2. Serve assets/frontend from the API (ie, rails static assets, Django collect static, etc). Downside is that you have to deploy everything together.

3. Reverse proxy so that api/frontend are on the same domain, and you can use cookies without CORS. Api lives at 'mydomain.com/api' and frontend at 'mydomain.com`

I am currently doing 3, which if you are using AWS, you can use CloudFront as the reverse proxy by using a separate dristriburion for your api and your Frontend and using behaviors to route traffic by path. In fact, that is what AWS recommends: https://aws.amazon.com/blogs/networking-and-content-delivery...

So for 3, for example:

You have CloudFront -> Loadbalancer -> EC2 for your api with a path of /api in CloudFront, you can set CloudFront to never cache. You don't pay for bandwidth between EC2 -> CloudFront, you only pay for bandwidth out of CloudFront:

>Outbound data transfer charges from AWS services to CloudFront is $0/GB. The cost coming out of CloudFront is typically half a cent less per GB than data transfer for the same tier and Region

For your frontend, you can host in s3 -> CloudFront with a catch all path for non-api paths (allows client side push state to work in SPA).

CloudFront in this case also is where SSL termination happens. You can also to full end to end ssl if you enable that in the CloudFront and your API can also terminate ssl at the LoadBalancer.

The other benefits to this approach is that you can usually just use the default auth systems for your web apps. You can also create a CNAME for your API loadbalancer to be api.mydomain.com and use that for non-web clients. In the case of Django Rest Framework, there is both cookie and token auth enabled by default.