There has been a bit of a gap between blog posts, but I have been productive. I have an authorization framework in place, and it is working quite well. It took me a while to get my head around JWT tokens again, but I have it working using AWS Cognito as my identity provider. The routing part of it is working pretty much as I had hoped:
override val router = routerFunction {
auth(CognitoJWTAuthorizer) {
get("/secure/route") { req: Request<Unit> -> Response.OK("This route is secured")}
}
}
The CognitoJWTAuthorizer
object looks in the request headers for an Authorizer: Bearer <token>
header, and extracts the token. It was a bit of a challenge working out how to verify that the token is legitimate, and eventually I found a Java library which can help with this.
CORS
Adding authorization has forced me to have to deal with CORS - Cross-Origin Resource Sharing which has, quite frankly, been a pain in the bum. I've had to make changes to my Router
, to my CDK Stack, to environment variables... usually I test the front end locally (on localhost) so I need a CDK deployment of Cantilevers which expects requests from localhost. But in "production", so to speak, I need a CDK deployment which expects requests from the real domain, https://www.cantilevers.org/ . So I'm currently switching between deployments to test and verify.
I am sure there is a better way, but I suspect I'll need additional AWS accounts to set up separate "dev" and "prod" CDK stacks. For now, I'll make do with what I have.
Pre-warming Lambda
The cold start up time of my API lambda function is becoming a real concern. I always knew it would be a problem writing the lambdas in a JVM language like Kotlin, but I thought I'd get away with it. Unfortunately, it seems different browsers have different timeout thresholds on making fetch
requests, and on MS Edge, my Lambda returns too slowly. Firefox has a more generous timeout, it seems.
My long-term hope is that I can deploy my lambdas as native images through a project called GraalVM, but that's a while away yet.
For now, I've implemented a 'pre-warming' route - as soon as the browser lands on the application, it makes a request to /ping
, even before the user has logged in. My hope is that by the time the user has logged in and returned to the application, the lambda will be warm enough to respond to the first real request (/structure
, which loads the list of existing blog posts).
Except, it turns out, that /ping
is a reserved route in API Gateway - so I make a request to /warm
instead. Whether this is having the intended result or not is hard to tell, but I'll keep exploring options.
Next steps
I really need to add the functions and routes to create new blog posts, and to load (and save) existing ones. So that's next.
Prev: Route Grouping (and an AI friend) Next: UI Struggles with Sveltekit and TailwindCSS