Marc
01/13/2025, 9:47 AMkotlinx.rpc
, and everything was working fine. Then I wanted to try authentication with it and realized that using the regular authentication plugin works the same way it does for regular WebSockets.
The issue arose when I tried to run it—the connection with the WebSocket never worked (I was testing in the JS build from a KMP project). I then tried the configuration suggested by @Aleksei Tirman [JB], but using the kotlinx.rpc
setup—and it worked! (Although in this case, my project was JVM-only.)
Next, I went back to my project and applied the JVM configuration—it ran without any issues. This leads me to believe that, for some reason, there is a missing piece in the JS build related to authentication that I might not be configuring correctly.
Any help is welcome! 🙏🏻Aleksei Tirman [JB]
01/13/2025, 10:49 AMAuth
plugin? Which auth provider do you use?Marc
01/13/2025, 12:00 PMJwt
one, exactly equal as the shown in the link, on the client I’m using io.ktor:ktor-client-js
Marc
01/13/2025, 12:01 PMfun rpcClient(): suspend () -> RPCClient = {
HttpClient {
installRPC()
}.rpc("<ws://localhost:8080/bire_api>") {
header(
HttpHeaders.Authorization,
"Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE3MzY1MTI1NzYsImV4cCI6MTczOTEwNDU3NiwiaXNzIjoiQmlyZUlzc3VlciIsImlkIjoxfQ.926fntQMb5qiu5W0fymOVIwRgAO-oSSTH5mJo53fOpTsNMEC-N7nuasSFJBVp1_-WIxQJ6vOR-cBiUGXNzYLzg",
)
rpcConfig {
waitForServices = true
serialization {
json()
}
}
}
}
Marc
01/13/2025, 12:03 PMcontext(Env.Auth)
fun Application.configureSecurity() {
authentication {
jwt {
realm = jwtRealm
verifier(
JWT
.require(Algorithm.HMAC512(secret))
.withClaimPresence("id")
.withIssuer(issuer)
.build(),
)
validate { credential ->
println(credentails are: $credentials) // <------- on Js this is not even printed on the rest builds yes
if (credential.payload.getClaim("id").asLong() != null) JWTPrincipal(credential.payload) else null
}
}
}
routing {
authenticate {
rpc("/bire_api") {
rpcConfig {
serialization { json() }
}
registerService<TransactionsService> { context ->
TransactionsRpcService.new(coroutineContext = context)
}
}
}
}
Marc
01/13/2025, 3:41 PMAleksei Tirman [JB]
01/14/2025, 1:04 PMAuthorization
header. To solve this problem, I suggest installing the CORS plugin to explicitly allow the Authorization
header.Marc
01/14/2025, 1:06 PMinstall(CORS) {
allowHeader(HttpHeaders.Authorization)
allowHeader(HttpHeaders.ContentType)
allowNonSimpleContentTypes = true
maxAgeDuration = 3.days
}
Aleksei Tirman [JB]
01/14/2025, 1:13 PMAuthorization
header can be received on the server?Marc
01/14/2025, 1:19 PMMarc
01/14/2025, 1:20 PMcontext(RoutingContext)
fun jwtTokenStringOrNul(): String? = (call.request.parseAuthorizationHeader() as? HttpAuthHeader.Single)?.blob
Aleksei Tirman [JB]
01/14/2025, 1:28 PMAuthorization
header is sent as part of the WebSockets
upgrade request with the JS engine?Marc
01/14/2025, 1:40 PMMarc
01/14/2025, 1:40 PMMarc
01/14/2025, 1:44 PMAleksei Tirman [JB]
01/14/2025, 2:42 PMMight happen that this limitation is propagated and can cause the issue of not being able to inject the headers?Yes, that could be the problem.