我对Rails和KotlinJs相当熟悉,但我是做auth的新手,我很困惑。
我设置了Rails Devise,并按照tutorials在线添加了JWT,除了我只使用用户名和密码。我还设置了Ktor前端如下:
const val backend = "http://localhost:3000"
val bearerTokenStorage = mutableListOf<BearerTokens>()
suspend fun login(username: String, password: String): Pair<HttpStatusCode, Json> {
val client = HttpClient(Js) {
install(Logging)
install(ContentNegotiation) { json(Json) }
install(HttpCookies)
// install(Auth) {
// bearer {
// loadTokens {
// bearerTokenStorage.last()
// }
// }
// }
}
val userData = User(user = UserData(username = username, password = password))
val response: HttpResponse = client.post("$backend/users/sign_in") {
headers {
append(HttpHeaders.AccessControlAllowOrigin, "*")
append("Credentials", "include")
}
contentType(ContentType.Application.Json)
setBody(userData)
}
console.log("Cookies: ", client.cookies("http://0.0.0.0:3000/"), client.cookies("http://0.0.0.0:8080/")) // returns null
if (response.status == HttpStatusCode.OK) {
val token = response.headers[HttpHeaders.Authorization]
console.log("Authorization Header: $token, ${bearerTokenStorage.firstOrNull()}") //returns null
// Handle successful authentication
} else {
console.log("auth failed")
// Handle authentication failure
}
// val jwtToken = client.readToken(response)?.getClaim("yourClaimName")?.asString()
println(response.bodyAsText())
client.close()
return Pair(response.status, JSON.parse(response.body()))
}
suspend fun getDataFromInputsAndSend(inputsContainer: HTMLElement): Json {
with(inputsContainer) {
val entries = rows.map { row ->
SaveEntries(
startTime = row.startTimeInput.value,
endTime = row.endTimeInput.value
)
}
val toSend = SaveData(...entries)
println(toSend)
return sendData(toSend)
}
}
suspend fun sendData(toSend: SaveData): Json {
val client = HttpClient(Js) {
install(ContentNegotiation) { json(Json) }
install(HttpCookies)
// install(Auth) {
// bearer {
// loadTokens {
// bearerTokenStorage.last()
// }
// }
// }
}
val response: HttpResponse = client.post("$backend/maslas") {
headers {
append(HttpHeaders.AccessControlAllowOrigin, "*")
append("Credentials", "include")
}
contentType(ContentType.Application.Json)
setBody(toSend)
}
return JSON.parse(response.body())
}
字符串
当我成功登录时,响应为:Authorization: Bearer eyJhb...
和Set-Cookie: _backend_session=%2F1vT...%3D%3D; path=/; HttpOnly; SameSite=Lax
。我被告知Set-Cookie应该通过Credentials: Include
保存在JS FetchApi中的浏览器中,但我不知道如何在Ktor中做到这一点。有人建议通过主体发送令牌,即使我几乎可以肯定这是错误的解决方案,如果我知道怎么做的话,我愿意试试。
1条答案
按热度按时间wz1wpwve1#
经过长时间的工作,我意识到我的错误是在rails后端:我已经按照指令暴露了header
'Authorization'
,但我在错误的函数中暴露了它,'Cors' initializer
,而不是我应该暴露的middleware
。一旦我正确暴露了header,Ktor也能够看到它,我就能够存储它并根据需要检索它。我的最终Ktor代码只有:
字符串