[HN Gopher] OAuth with Cloudflare workers on a statically genera...
___________________________________________________________________
OAuth with Cloudflare workers on a statically generated site
Author : vonadz
Score : 167 points
Date : 2021-11-15 10:54 UTC (12 hours ago)
(HTM) web link (abyteofcoding.com)
(TXT) w3m dump (abyteofcoding.com)
| Lucasoato wrote:
| I absolute love the graph, really. When the idea is simple and
| easy, you don't need hundreds of tools, just the plain old paint
| is fine.
| vonadz wrote:
| Thanks :) paint is the graphic editor I'm most proficient in!
| jimhi wrote:
| Fantastic use of workers!
|
| I added the ability to do captcha submissions from my site and
| send alerts to slack myself. I opted not to go the worker route
| as I found the language a bit hard to use and I could get the
| same effect with just javascript pulling other dynamic javascript
| hosted elsewhere.
|
| (You can see an example with the submission form at the bottom of
| this page: https://mrsteinberg.com/how-to-kill-your-startup-co-
| founder-...)
| ignoramous wrote:
| > _Fantastic use of workers!_
|
| Well, when you think of Workers as Nginx, Squid, Memcached as-
| a-service, the possibilities simply present themselves. It is
| absolutely appalling that AWS has Lambda@Edge (relatively, uber
| expensive) and CloudFront Functions (uber lame) positioned
| against Workers.
|
| Full-stack week starting today, and it is very likely that
| Cloudflare launch _Container_ support for Workers:
| https://blog.cloudflare.com/full-stack-week-2021/
|
| Let's see if Adam Selipsky announces anything compelling at
| re:invent aloof from their Lightsail initiatives which are
| priced similar to Cloudflare (and cheap only if you're running
| toy products atop, but not any SaaS-like services).
| tyingq wrote:
| > I opted not to go the worker route as I found the language a
| bit hard to use and I could get the same effect with just
| javascript pulling other dynamic javascript hosted elsewhere
|
| I'm confused by this since the default language for Workers is
| javascript. Do you mean their api is confusing?
| adamkochanowicz wrote:
| Same question.
| jimhi wrote:
| I answered above - looking at their site it appears there is
| much more documentation. It was hard to wrap my head around
| what it was doing / the APIs when I wrote this
| vonadz wrote:
| Thanks! I'd like to explore adding debugging and warning alerts
| in the future. Right now it's kind of hard to tell if anything
| is broken, short of going through the registration process
| myself. If you're pulling javascript hosted somewhere else to
| your site, doesn't that expose your slack API key?
| jimhi wrote:
| I should have explained more. The javascript is dynamically
| created and hosted on S3. The keys, etc are safely on a
| server that runs to generate the file. I built this around
| the time Cloudflare first released workers, their
| documentation seems much less confusing now.
| vonadz wrote:
| I'm having a hard time understanding how a file hosted on
| S3 can send a request to Slack without exposing your API
| key. Can you elaborate on that?
|
| EDIT: guessing by the delay in response, someone just told
| all of HN they exposed their API key?
| DangitBobby wrote:
| My understanding is that they used cloud functions. Code
| is being executed on someone else's server, not the
| client, so the keys don't have to be shared with the
| client.
| vonadz wrote:
| That would be the logical solution, but "The javascript
| is dynamically created and hosted on S3. The keys, etc
| are safely on a server that runs to generate the file"
| sounds a lot like they have a server where they build a
| .js file that is capable of querying Slack, then store
| that file on S3 for the website to pull whenever someone
| registers. In that case, the client is pulling a .js file
| that probably has the Slack API key in it.
| [deleted]
| fzaninotto wrote:
| I don't understand how you can log out using this method, and
| that's very concerning. You're basically logged in forever?
| vonadz wrote:
| There is no logout because the login isn't really a login. All
| this is doing is using the user's permission to submit their
| email (registered on the OAuth service) to subscribe to the
| newsletter. Nothing in the browser is changing that could
| compromise your details.
| intricatedetail wrote:
| Can you self host these workers? Otherwise you get vendor lock in
| which is a no go.
| ignoramous wrote:
| Yes, miniflare [0] lets you run Workers locally, but I wouldn't
| treat it to production traffic.
|
| There's also Deno, which is _very_ similar in technology to
| Workers [1].
|
| Others are building "Workers" atop WebAssembly, and things are
| looking up on that front as well [2][3].
|
| See also: https://github.com/debarshibasak/awesome-paas
|
| [0] https://github.com/cloudflare/miniflare
|
| [1] https://deno.land
|
| [2] https://github.com/suborbital/atmo
|
| [3] https://github.com/krustlet/krustlet
| vonadz wrote:
| Self hosting would pretty much defeat the whole purpose of
| workers. The point is that you don't need to self host.
| nicoburns wrote:
| The point is that you don't need to host them in production.
| Being able to self-host is still very useful for testing and
| local development workflows
| lsaferite wrote:
| Their point is, can you mitigate vendor lock-in if you need
| to do so? The fact that you don't even consider that is a sad
| commentary in itself.
| ezfe wrote:
| It's regular Javascript, so if you program it properly then
| you can re-use a lot of code with minimal work. Depends on
| how you architect your project to say how easy it would be.
| vonadz wrote:
| If their point was can you mitigate vendor lock-in, they
| should have said that instead of asking about self-hosting.
| Saying you have vendor lock-in because you can't self-host
| something is very strange in the context of this article.
|
| I didn't make a point of vendor lock-in because migrating
| this process flow to a self-hosted HTTP server would take
| about 5 minutes. On top of that, this flow is going to be
| very similar for any vendor offering javascript functions.
|
| Perhaps it is my fault for not including a section
| discussing this, but I assumed that the audience for this
| would primarily be people understand basic javascript and
| could deduce the portability of the code by looking at it.
| jbergstroem wrote:
| At my company we've been using workers extensively for routing,
| specific auth logic (including integration with Auth0) and more
| -- I guess moving towards an api gateway pattern. I loved it at
| first but its becoming very cumbersome to maintain. I'm currently
| migrating away from this pattern and try to keep logic closer to
| the application/code that leans on it.
|
| tl;dr: Orchestrating many cloudflare workers at scale has not
| been a great experience.
| vonadz wrote:
| Yeah I don't find this at all surprising. Ultimately it's
| always a balance of what's worse to maintain, the reality
| (server) or the abstraction (workers).
| techthumb wrote:
| From the article itself: ... one might think
| implementing OAuth sign up is relatively trivial; after all, you
| just need to write a fetch request that redirects the user to the
| OAuth page, then another request that sends their email to the
| newsletter service of choice to sign them up. Well, the issue is
| that in order to do the second step of that process, one needs to
| hit an API endpoint that requires authentication (an API key).
| That is essentially a password and not something you want to
| expose on the front end and give everyone access to.
|
| The OAuth Authorization Code Flow with Proof Key for Code
| Exchange (PKCE) solves this problem without needing a worker.
|
| This article Auth0 does a good job of explaining PKCE:
| https://auth0.com/docs/authorization/flows/authorization-cod...
| vonadz wrote:
| I think you misunderstood what I said. The API key I don't want
| to expose is the one that is required to register the user with
| the newsletter service, not the client key for the OAuth
| service.
| DaiPlusPlus wrote:
| OAuth doesn't use "API keys". Please clarify.
| vonadz wrote:
| "not the client key for the OAuth service"
|
| OAuth uses a client key and/or a client secret, for the
| application that is requesting access on behalf of the
| client.
| DaiPlusPlus wrote:
| OAuth + OIDC only uses client-secrets when using the
| client_credentials flow, which is only for us with non-
| human software, or when a client needs to authenticate
| and authorize itself independently of any human user.
| When humans are involved you won't be using
| client_credentials, you'll be using 'implicit' or 'code'
| (preferably with PKCE) - but ONLY when the client can
| actually safely store secrets - so static-website SPAs
| simply can't.
|
| While non-human client-credentials can be used in-
| conjunction with a human-user's credentials it's largely
| unnecessary as an unauthorized client wouldn't be able to
| authenticate with a human-user because the redirect_uri
| sent from the client would be rejected automatically (and
| if that worked, there's always 'aud' audience filtering
| too), so the human-user wouldn't even be prompted to
| authenticate, they'd get an error message.
| DaiPlusPlus wrote:
| The problem isn't about secure transmission of the
| access_token, it's about secure storage of the access_token:
| it's impossible to safely and securely store secrets in
| browser-based (JS) OIDC clients when using OIDC's Implicit
| flow, which is the only flow that works with client-side-JS
| applications (especially SPAs).
|
| Conventional web-applications let the application server store
| per-user secrets (e.g. access_tokens). If the application
| server needs to be stateless then secrets are packed into a
| web-browser cookie with the "httponly" and "secure" attributes
| which prevents any and all client-scripts from accessing them.
| Of course browser cookies are not the same thing as a true
| Bearer Token, so this means that when using an SPA the SPA
| cannot make its own HTTP requests to other RPs, it needs to use
| some non-local secret-storing-proxy to make the request for
| it... which starts to make a mockery of how microservices
| should operate.
|
| Code Flow with PKCE does not replace the Implicit flow. Also,
| the Auth0 article you linked to is not a "good job". On the
| contrary, that article talks about using client-secrets - which
| you *must never have* in a JS-only/SPA/static client.
|
| The only real solution would be some kind of opaque OIDC client
| built-in to a browser that handles secrets-storage on-behalf of
| JS applications (such that JS code never gets to see or handle
| any secrets, including the auth code and access_token, but the
| OIDC identity_token should be exposed, of course). I'm
| surprised Google and Mozilla haven't done this already...
| noahmasur wrote:
| Why not just use Cloudflare Access for this? It's the same thing
| for even less work (and it's free for personal use).
| vonadz wrote:
| Did you read the article?
| judge2020 wrote:
| This worker might be cheaper depending on how heavy your app is
| (eg. how many requests this worker triggers on) versus Access
| if you have >50 users.
| vonadz wrote:
| Not quite sure why my other comment got flagged, it was a
| genuine question. If they had, and they still suggested this, I
| would inquire how that would be possible. It appeared to me
| that they had just read the title of the article and suggested
| something related to it.
|
| As far as I can tell, Cloudflare Access doesn't allow you to
| run arbitrary code in an environment that isn't exposed to the
| user, which is kind of the whole purpose of this setup. The
| sole purpose of the OAuth part of this operation is so that the
| user doesn't have to type in their email. Session
| persistence/selective access isn't relevant here, and that
| appears to be the only thing the Cloudflare Access really
| offers.
| nawgz wrote:
| "Instead of using a single server with NGINX and an API on it, I
| use multiple external hosted services that cost more-per-request
| than an old-school setup with less portability and more vendor
| lock-in"
|
| This isn't even a technical accomplishment in any way, it's just
| slapping together a few managed services together to sign up
| someone for a newsletter. I cannot imagine being the one to
| maintain a signup flow like this, it certainly looks
| unnecessarily painful from here.
| vonadz wrote:
| In regards to your quote, this is free and if I wanted to
| switch, I could just copy and paste the javascript into node
| with some minor tweaks.
|
| A big motivator for this was definitely just to try out
| Cloudflare workers and see how they are. I've set up countless
| servers for APIs. In terms of time, I'd say Cloudflare workers
| is a bit faster when you get over the initial learning curve.
| Obviously you could write a deploy script for a server and have
| it set up everything automatically, and I have done that in the
| past, but sometimes it's fun to try new things right?
|
| I never intended for this to come across as a technological
| accomplishment. I even end the article with "That's pretty much
| it. It's fairly simple with no real catches". I'm merely
| presenting what I thought would be useful information for some
| people. Personally I think maintaining a server is more work
| than maintaining this, but to each their own.
| jffry wrote:
| Thanks for sharing a small writeup of a neat thing you did! I
| think maybe the parent comment missed the context, which is
| that you wanted to add an email signup to an otherwise static
| site.
|
| In that context, setting up a VPS would now mean that you
| have to be responsible for a new pet, including security
| updates and monitoring. You would also have to change your
| deployment tooling / workflow to something quite different
| (pushing and restarting a running service, rather than just
| running aws s3 sync ...)
|
| Of course I don't think I would take this approach if I
| already had a backend service hosting a site, but I certainly
| would experiment with it if I were in your situation.
| toastal wrote:
| To quote Sourcehut Pages Limitations
| (https://srht.site/limitations)
|
| > Connections from CloudFlare's reverse proxy are dropped. Do not
| help one private company expand its control over all internet
| traffic.
|
| We really to not let the internet become so centralized.
| SergeAx wrote:
| They are working via WARP VPN, which is good. I wonder how do
| they differ those services, by headers only?
| GrayShade wrote:
| Good, it's not up to Sourcehut to decide how I should expose a
| web service (or browse the Internet FWIW).
| roberto wrote:
| They're not? You're free to not use Sourcehut.
| miyuru wrote:
| Cloudflare is the only provider that I know of that provides
| IPv6 reverse proxy for free with fair limits.
|
| If it wasn't for them most of my sites won't be accessible for
| more than half of the internet.
| guilhas wrote:
| For "free"
|
| Also maybe there is a reasons for most of the internet not to
| care about ipv6 or current implementation, but that is
| another different big debate
| ohyeshedid wrote:
| What would those reasons be?
| Eikon wrote:
| Even if I don't agree with his opinion, I really don't
| understand why so much people actually use cloudflare.
|
| SSL is a solved problem since let's encrypt, cloudflare
| actually decreases performance (by adding an hop when serving
| dynamic content). For most websites, DDoS attacks are a non-
| issue.
|
| It just feels like, unnecessary technology?
| handrous wrote:
| Their service is great if you take money online at all. The
| $200/m tier plan, that is. I gather the $5,000+/m custom
| plans are nice if you need all the extra networking features,
| though way overpriced if you just need basic CDN features--
| which includes some kind of firewall, DDOS protection,
| e-commerce attack protection (e.g. anti-credit-card-stuffing)
| and light routing/rewriting/"worker" features at this point,
| all of which are quickly becoming table stakes in that
| market.
|
| The free tier is great for serving low-value (that is, not
| enough value that you _need_ a SLA from your vendor) static
| sites for pennies a month.
|
| Having so much in one place is _really_ nice for small shops.
|
| But they 100% are on track to be the next Big Bad of the tech
| world, and they're heading that way very much on purpose.
| Their entire strategy for how they've positioned themselves
| is, transparently, bent toward making themselves the Web's #1
| middle-man.
| GrayShade wrote:
| I've recently started using their DNS service and I've been
| using 1.1.1.1 for a couple of years now. I think Cloudflare
| has done more for the Internet than a lot of other large
| companies, and I'm inclined to trust them regardless of what
| the sr.ht founder says.
|
| Their CAPTCHAs are annoying, though, and I wouldn't miss them
| an ounce if they went away.
| handrous wrote:
| The CAPTCHAs are probably over-applied by people who use
| the defaults, but they're absolutely necessary for some
| sites, especially e-commerce. The alternative would be
| flat-out blocking requests that trigger the CAPTCHAs. An
| absolute _shitload_ of traffic on the Internet is the
| abusive sort, and lots of that 's aimed at sites that
| accept CC payments. Used correctly, CAPTCHAs mean you don't
| have to blackhole as much traffic, so actually _increase_
| the fraction of people who can reach your site, versus some
| other world without them where you 'd just be forced (by
| costs & risks of dealing with abuse) to drop those
| requests.
| Nextgrid wrote:
| If your problem is credit card fraud you can simply
| enforce 3D Secure (which offloads liability) for requests
| that are considered risky. The customer can then choose
| to either use a 3DS-supported card or complete a
| captcha/etc.
| vonadz wrote:
| I feel like I've single-handedly trained their AI to
| identify buses, boats, and planes at this point.
| anamax wrote:
| I've never gotten planes. Buses and boats are very rare
| (for me).
|
| I mostly get crosswalks and traffic lights. I
| occasionally get mountains, motorcycles, and bicycles.
| [deleted]
| vonadz wrote:
| You don't get them because I've done them all!
| technobabbler wrote:
| The CAPTCHAs are a per-website setting that individual
| webmasters set (or, more likely, forget to set).
|
| As an end user, I agree they are annoying. These two things
| may or may not help (hCaptcha is the engine used by
| Cloudflare*):
|
| 1) You can set an accessibility cookie that should be good
| for a while: https://www.hcaptcha.com/accessibility
|
| 2) There is also the Privacy Pass beta, which lets you
| redeem CAPTCHA solves for "tokens" that can be used for
| later CAPTCHAs https://www.hcaptcha.com/privacy-pass
|
| But yeah, hCaptcha is really annoying, especially compared
| to the auto-solve of reCAPTCHA when you're logged in to a
| Google account.
|
| * Cloudflare switched to hCaptcha in 2020:
| https://blog.cloudflare.com/moving-from-recaptcha-to-
| hcaptch...
| technobabbler wrote:
| > SSL is a solved problem since let's encrypt
|
| Only if you remember to update your cert chains, and your web
| servers have to keep up with TLS etc. updates too
|
| > cloudflare actually decreases performance (by adding an hop
| when serving dynamic content).
|
| If your dynamic content doesn't require true real-time
| updates (like a forum or chat or something), but can be
| limited to once a minute updates or similar (like a reddit-
| style front page), caching and global CDNs can still
| drastically speed that up for users who aren't near your data
| center.
|
| And that's just their static cache offering. If you build
| your site around their edge infrastructure (workers, workers
| KV, durable objects), you can entirely remove the last hop by
| handling client requests and sharing state across the CDN
| itself. Two of their demos show IRC-like chat and Doom (the
| game) running entirely on the edge:
| https://github.com/cloudflare/workers-chat-demo
| https://blog.cloudflare.com/doom-multiplayer-workers/
|
| They also do other performance boosts, like auto-optimizing
| images, converting to webp, minifying stylesheets & scripts,
| dynamic loading, http QUIC, etc. And they offer a edge
| streaming solution for video (although Vimeo is probably much
| cheaper for most use cases).
|
| > For most websites, DDoS attacks are a non-issue.
|
| It can also help with things like Google Analytics bot spam,
| drive-by vulnerability scans against certain web servers or
| Wordpress, etc. It's not just a IP blacklist but does some
| degree of traffic analysis.
|
| And all of that is available for free or cheap. It's very
| difficult to do all that yourself as a small-biz or solo web
| dev, even if you had full time dev-ops.
|
| As for "the internet shouldn't be controlled by a single
| entity", sure, but it's always been a corporate network.
| Choose your nemesis: Cloudflare, Google, Amazon, Facebook,
| Verisign/network solutions (in the old days)... there's never
| been a truly free internet. At least Cloudflare is doing a
| darned good job of stewarding the internet.
| thefounder wrote:
| Free DNS, Free CDN, easy to use the user interface, APIs,
| they use Go
| kentonv wrote:
| > cloudflare actually decreases performance (by adding an hop
| when serving dynamic content).
|
| Page load time tends to be dominated by static content.
|
| But even for dynamic content, this isn't necessarily true.
| Setting up a TLS connection requires multiple network round
| trips. When using an edge network, those round trips only
| need to go to the nearest PoP rather than all the way to the
| server. If the PoP already has connections open to your
| server (which is probably the case if you have consistent
| traffic) then the network round trips back to your origin
| server are avoided, and your dynamic content ends up being
| served faster.
|
| Additionally, Cloudflare's Argo Smart Routing is often able
| to route packets across the internet faster than than default
| network routing, which speeds up the communications between
| Cloudflare and your origin server.
|
| So it turns out "adding a hop" does not necessarily decrease
| performance.
|
| (Disclosure: I work for Cloudflare.)
| DaiPlusPlus wrote:
| > Setting up a TLS connection requires multiple network
| round trips
|
| QUIC significantly reduces the cost of the TLS handshake, I
| think now it's only a single additional packet-exchange:
| https://blog.cloudflare.com/the-road-to-quic/
| tick_tock_tick wrote:
| Most traffic is not QUIC yet maybe in the future.
| vonadz wrote:
| For my static site, it substantially decreased loading times
| compared to when I just host from a VPS.
| DrBenCarson wrote:
| Your qualification there is important--dynamic content.
| Static content remains by far the primary source of internet
| traffic. Streaming video is over 65% of all mobile traffic by
| volume. That doesn't even account for mobile images.
| stoned wrote:
| SourceHut and its founder are the promulgators or a never ended
| stream of strong opinions and principled edicts that do little
| but alienate people. Drew's solution to every problem is
| blocking and blackholing [0] which makes him seem weak and
| petty and suggests that by refusing to work constructively with
| people he's mostly interested in strongarming and asserting
| dominance. I find it pretty hard to take him seriously and run
| from anything he's associated with, even when I agree. There's
| this concept called "non-violent communication" that he would
| be well-served to explore.
|
| https://github.com/makeworld-the-better-one/amfora/issues/19...
| vonadz wrote:
| Promulgators... nice. Saving that in the lexicon for future
| use.
| stoned wrote:
| s/promulgators or/promulgators of/
|
| Yeah, it's usually used in the context of the unilateral
| issuing of decrees.
| vonadz wrote:
| Sounds as pretentious as what it describes.
| [deleted]
| ectopod wrote:
| Non-violent communication works if you're talking to an
| individual as an equal but corporations cannot empathise or
| be empathised with. It's madness to try.
| [deleted]
| stoned wrote:
| The open source developer of amfora is about as far as you
| can get from a corporation, though. And behind every
| cloudflare reverse proxy connection is a human. Blocking
| them for nothing other than their choice of Internet route
| stands antithetical to the foundational spirit of the net,
| which he is ostensibly trying to protect.
___________________________________________________________________
(page generated 2021-11-15 23:01 UTC)