【发布时间】:2020-10-11 04:18:38
【问题描述】:
一段时间以来,我一直在用头撞墙,试图弄清楚这里出了什么问题。我创建了一个简单的 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。
【问题讨论】:
-
我也有同样的问题!!!花了1天时间弄清楚。有进展吗?
-
你有一个示例项目来尝试重现这个吗?