Hey I was wondering if it was possible to get a re...
# ktor
t
Hey I was wondering if it was possible to get a request principal from a call in RateLimit, I'm trying to get the request principal to get a UUID to identify users but it just returns null.
a
The following code works for me:
Copy code
embeddedServer(CIO, port = 4444) {
    install(Authentication) {
        basic {
            validate { creds ->
                if (creds.name == "John") UserIdPrincipal(creds.name) else null
            }
        }
    }

    install(RateLimit) {
        register(RateLimitName("protected")) {
            rateLimiter(limit = 5, refillPeriod = 60.seconds)
            requestKey { call ->
                val user = call.principal<UserIdPrincipal>()
                user?.name ?: "default"
            }
        }
    }

    routing {
        authenticate {
            rateLimit(RateLimitName("protected")) {
                get("/secret") {
                    call.respondText { "secret" }
                }
            }
        }
    }
}.start(wait = true)
Please provide more details about your problem.
r
I have got the same problem using the JWT plugin.
call.principal<Principal>()
in
requestKey
always returns null.
When changing the provider to global in your code snippet @Aleksei Tirman [JB] the principal in `requestKey`becomes null . Is this a bug or intended?
a
Unfortunately, this isn’t gonna work with a global rate limiter.
r
Can you give a brief technical explanation of why this is? It's not a big deal however, now I just have to wrap all my endpoints in a rateLimit(name)-block
r
Short explanation is that global rate limiter works on
Application
pipeline, but auth works or
Route
. And phase where
RateLimit
plugin works is executed before route matches.
t
Ah sorry I forgot about this message, I’ll be sure to read everything later
Ah @Rustam Siniukov, thanks for your explanation, so it is just required to wrap all routes manually to do rate limiting like that?
r
yes, this is the easiest solution