Is there any extra configuration we need to set up...
# ktor
m
Is there any extra configuration we need to set up if we want to enable the authentication plugin for JS Ktor? Context: I started experimenting with
kotlinx.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! 🙏🏻
a
Can you describe the expected and the actual outcome when the JS engine is used with the
Auth
plugin? Which auth provider do you use?
m
on my backend I’m using the
Jwt
one, exactly equal as the shown in the link, on the client I’m using
io.ktor:ktor-client-js
actually this config:
Copy code
fun 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()
            }
        }
    }
}
if it helps, the server one is as follows:
Copy code
context(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)
            }
        }
    }
}
is it possible that websockets on JS does not allow injecting the auth bearer header?
a
One reason could be the browser environment, which, because of security considerations, blocks the sending of the
Authorization
header. To solve this problem, I suggest installing the CORS plugin to explicitly allow the
Authorization
header.
m
I do already, but this doesn’t work 😕 I’m just thinking to maybe create a session authentication? so i logig with http and keep a session that I’ll use when connmecting to the websocket? does it make sense?
Copy code
install(CORS) {
        allowHeader(HttpHeaders.Authorization)
        allowHeader(HttpHeaders.ContentType)
        allowNonSimpleContentTypes = true
        maxAgeDuration = 3.days
    }
a
Can you verify that the
Authorization
header can be received on the server?
m
is is, for all my http calls the auth works as expected
this is the way I use to get the auth header form all my http requests:
Copy code
context(RoutingContext)
fun jwtTokenStringOrNul(): String? = (call.request.parseAuthorizationHeader() as? HttpAuthHeader.Single)?.blob
a
So the problem occurs only when the
Authorization
header is sent as part of the
WebSockets
upgrade request with the JS engine?
m
yes
I tried with JVM, iOS and Android and all looks good
I found this thread over stack overflow. It’s not ktor related but websockets on js instead. Might happen that this limitation is propagated and can cause the issue of not being able to inject the headers?
a
Might 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.