Я бился головой об стену, пытаясь понять, что здесь не так. Я создал простой сервер Ktor, который позволяет вам создать пользователя, который должен вернуть токен пользователю и сохранить сеанс. Затем я хочу, чтобы конечная точка с проверкой подлинности позволяла удалить пользователя. Однако аутентифицированный вызов загружает пустой сеанс и не может найти пользователя, поэтому его нельзя удалить. Любая помощь будет оценена по достоинству! Код здесь:
Application.kt
...
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)
@Suppress("unused")
@kotlin.jvm.JvmOverloads
fun Application.module(testing: Boolean = false) {
install(Locations) {
}
install(Sessions) {
cookie<MySession>("MY_SESSION") {
cookie.extensions["SameSite"] = "lax"
}
}
DatabaseFactory.init()
val db = MyRepository()
val jwtService = JwtService()
val hashFunction = { s: String -> hash(s) }
install(Authentication) {
jwt("jwt") { //1
verifier(jwtService.verifier) // 2
realm = "My Server"
validate { // 3
val payload = it.payload
val claim = payload.getClaim("id")
val claimString = claim.asInt()
val user = db.findUser(claimString) // 4
user
}
}
}
install(ContentNegotiation) {
gson {
}
}
routing {
users(db, jwtService, hashFunction)
}
}
UserRoute.kt
...
const val USERS = "$API_VERSION/users"
const val USER_CREATE = "$USERS/create"
const val USER_DELETE = "$USERS/delete"
@KtorExperimentalLocationsAPI
@Location(USER_CREATE)
class UserCreateRoute
@KtorExperimentalLocationsAPI
@Location(USER_DELETE)
class UserDeleteRoute
@KtorExperimentalLocationsAPI
fun Route.users(
db: Repository,
jwtService: JwtService,
hashFunction: (String) -> String
) {
post<UserCreateRoute> {
val request = call.receive<CreateUserRequest>()
val password = request.password
?: return@post call.respond(
HttpStatusCode.Unauthorized, "Missing Fields")
val email = request.email
?: return@post call.respond(
HttpStatusCode.Unauthorized, "Missing Fields")
val hash = hashFunction(password)
try {
val newUser = db.addUser(email, hash)
newUser?.userId?.let {
call.sessions.set(MySession(it))
call.respondText(
jwtService.generateToken(newUser),
status = HttpStatusCode.Created
)
}
} catch (e: Throwable) {
call.respond(HttpStatusCode.BadRequest, "Problems creating User")
}
}
authenticate("jwt") {
delete<UserDeleteRoute> {
try {
val userId = call.sessions.get<MySession>()?.userId
if (userId == null) {
call.respond(
HttpStatusCode.BadRequest, "Problem retrieving User")
return@delete
}
if (db.deleteUser(userId)) {
call.respond(HttpStatusCode.NoContent, "User deleted")
} else {
call.respond(HttpStatusCode.BadRequest, "Failed to delete user")
}
} catch (e: Exception) {
application.log.error("Failed to delete user")
call.respond(HttpStatusCode.BadRequest, "Failed to delete user")
}
}
}
}
Есть что-то, что я ' м пропал? Токен успешно возвращен, а затем мой запрос на удаление направляется в нужное место, но строка val userId = call.sessions.get<MySession>()?.userId
каждый раз возвращает null.