Where is the year going?

And we thought 2020 was bad, right? Well damn, 2021 has been even worse - at least, in terms of things to keep me insanely busy. Mostly day-job work things which I can’t really write much about (other than to say we’re working on some very cool tech), hence I’ve been failing to write anything here for nearly six months.

I love Rust. I hate Rust.

One of the things that has been keeping me busy is doing battle with the Rust programming language. Rust is absolutely brilliant… Unfortunately, Rust is also fantastically infuriating. As I’ve said to many people:

Rust makes complicated problems really simple. Rust also makes really simple things into incredibly complicated problems.

What really helps is that there is a fantastic collection of libraries (also known as Crates) developed by the Community on crates.io; what often hinders is that there is a fantastic collection of libraries on crates.io, each of which is subtly incompatible thanks to a peculiarly Rust form of dependency hell.

Things that appear that they ought to work just don’t, often for barely penetrable reasons, because they have dependencies on different versions of the same frameworks. Often you’ll discover this at compile time and spend a few hours scratching your head trying to work out why none of the ‘working’ examples you’ve seen actually, well, works; more perniciously, sometimes you’ll only find out at runtime. If you’ve ever seen an error like this, you know what I mean:

there is no reactor running, must be called from the context of a Tokio 1.x runtime

Tokio is one name that often appears with this kind of thing. The Rust async patterns/frameworks are immature, and evolving fast - and tokio (the most popular of the runtimes for Rust async) made big breaking changes between version 0.2 and 1.x. Unfortunately, 0.2 was the standard pretty much for a long time, and now we are in a situation where half the publicly available crates work with 0.2, the other half with 1.x, and the two will not play together nicely in the same project. And often you won’t find out ‘til runtime.

Argh.

JWT bearer authentication and Actix-Web 4

So, to cut a long story short, I ended up facing this exact problem with the - excellent - Actix-Web web framework and another crate, a CouchDB client library (couch_rs).

couch_rs uses the latest version of Tokio. Actix-web, naturally, does not. Sigh.

But, there is a beta version of Actix-Web which is using the new framework! Hurrah. I updated my Cargo.toml to use the new version, and thankfully my application with CouchDB builds and runs. Except…

Except now, the Actix middleware for validating JWT tokens (for authorising the Actix API I am building) now doesn’t work. Arrrrrrrrrgh.

The Solution

The solution, I decided, was to stop fighting with dependency hell, and to remind myself of the question - Have we forgotten how to program?. Seriously, if you haven’t read David Haney’s blog post by that name, go away and do so.

How hard can it be to just write your own middleware to authorise JWT tokens? Really not too hard, if you have very simple requirements. And I do, indeed, have very simple requirements.

So, I’ve rolled my own middleware for validating JWT tokens that does work with Actix 4. Right now, it does exactly what I need it to and no more, but I can envisage it might get fiddled with a little over time and maybe grow some more features, and indeed maybe it will be useful to someone else stuck in my particular cul-de-sac of dependency hell, so I’ve published it on crates.io as well for anyone else to use. Be my guest :).

What Where
Documentation https://jwt-actix4.snowgoons.ro/jwt_actix/
Crate https://crates.io/crates/jwt-actix4
Cargo ref jwt-actix4 = "0.1.0"