Hello guys. Am working on a ktor project where am ...
# ktor
i
Hello guys. Am working on a ktor project where am using sessions to store the current userId. I have followed the docs but anytime i want to get my session for userId i am receiving null. I have seen several pple go through this but i haven't found a solution yet. Here is my code and depedencies am using. My Application Class
Copy code
fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)

@KtorExperimentalAPI
@KtorExperimentalLocationsAPI
@Suppress("unused") // Referenced in application.conf
fun Application.module() {
    install(Locations) {
    }

    install(Sessions) {
        cookie<MySession>("MY_SESSION") {
            cookie.extensions["SameSite"] = "lax"
        }
    }

    DatabaseFactory.init()
    val userRepository = UserRepositoryImp()
    val taskerRepository = TaskerRepositoryImp()
    val requestRepository = RequestRepositoryImp()
    val messageRepository = MessageRepositoryImp()
    val reviewRepository = ReviewRepositoryImp()
    val jwtService = JwtService()
    val hashFunction = { s: String -> hash(s) }

    install(Authentication) {
        jwt("jwt") {
            verifier(jwtService.verifier)
            realm = "Tasksfy"
            validate {
                val payload = it.payload
                val claim = payload.getClaim("id")
                val claimString = claim.asInt()
                val user = userRepository.getUser(claimString)
                user
            }
        }

    }

}
My userRoute class for login.Where am storing the session id
Copy code
@KtorExperimentalLocationsAPI
fun Route.users(db: UserRepository, jwtService: JwtService, hashFunction: (String) -> String) {

    post<UserLoginRoute> {
        val signInParameters = call.receive<Parameters>()
        val password =
            signInParameters["password"] ?: return@post call.respond(HttpStatusCode.Unauthorized, "Missing Fields")
        val phoneNumber = signInParameters["phone_number"] ?: return@post call.respond(
            HttpStatusCode.Unauthorized,
            "Missing Fields"
        )

        val hash = hashFunction(password)

        try {
            val currentUser = db.getUserByPhone(phoneNumber)
            currentUser?.user_id?.let {
                if (currentUser.password == hash) {
                    call.sessions.set(MySession(it))  //Storing the user id here
                    val token = jwtService.generateToken(currentUser)
//                    call.respondText(jwtService.generateToken(currentUser))
                    call.respond(
                        ResponseDefault(
                            BaseResponse(true, "Welcome back " + currentUser.first_name, token),
                            currentUser
                        )
                    )
                } else {
                    call.respond(BaseResponse(false, "Invalid Login details!", ""))
                }
            }

        } catch (e: Throwable) {
            application.log.error("Failed to register user", e)
            call.respond(BaseResponse(false, "Problem retrieving User.Try again later! " + e.message,""))
        }
    }
My Session Class
Copy code
data class MySession(val userId : Int) {
}
Here is my depedencies incase there could be problem
🧵 3
a
Could you please check are you able to set data for a session without interaction with a database? Also, I don't see the code for retrieving data from a session.
i
Here is my code where i am retrieving the session. I have put them in away that i can be able to fetch certain data associated with a specific user.Thats why i need to know the current userId immediately after logging in
Copy code
get<RequestsRoute> {
            val userId = call.sessions.get<MySession>()?.userId
            try {
                val requests = userId?.let { it1 -> db.getAllRequestsById(it1) }
                call.respond(ResponseDefault(BaseResponse(true, "Requests retrieved successfully", userId.toString()), requests))

            } catch (e: Throwable) {
                application.log.error("Failed to retrieve requests ", e)
                call.respond(BaseResponse(false, "Problems retrieving requests " + e.message, ""))
            }
        }
Here is a link to my depedencies https://kotlinlang.slack.com/archives/C0A974TJ9/p1632886098331100
a
When I remove the code that interacts with a database then saving user ID in a session and retrieving it works as expected. I suggest to debug your application to make sure that the
call.sessions.set
call is actually executed. Please share a complete project or remove database dependency, otherwise it's very difficult to troubleshoot your problem.
i
Thanks @Aleksei Tirman [JB] I have tried setting a value to my session.but it seams that my call.sessions.set isn't executed.let me try fixing it now that i know where the problem is.incase of anything i will reach out
Hey @Aleksei Tirman [JB].My problem is based on a ktor course by @raywenderlich. My objective is to store the userId during logging so that i can be able to fetch requests associated wit that user through relationship. Here is a link to the whole project. I have tried to find a work around on how to set the session but with no avail. Any help will be highly appreciated. https://www.raywenderlich.com/7265034-ktor-rest-api-for-mobile
a
I've created a working sample project guided by the article you gave. To test it you need to update environment variables in the run configuration to make a proper connection to a database. Make a POST request to
<http://localhost:8080/v1/users/create>
to create a user, then POST request to
<http://localhost:8080/v1/users/login>
to update the session and a GET request to
<http://localhost:8080/v1/users>
to display greetings for a user.
i
Hello @Aleksei Tirman [JB] Am very grateful for your assistance. I tried the rest_mobile in ktor that you sent and it works fine. I have changed my depedencies to match with those in your project. I was using ktor_version=1.4.1 to 1.6.3 My server runs fine but when i try accessing routes it issues an error "The server returned an invalid or incomplete HTTP response." Here is the running project with ktor_version=1.4.1 sessions not working. I suspect that i might be missing out on old versions of dependencies. Your assistance will be highly appreciated.
a
Could you please explain to me why do you use an outdated version of Ktor? There are probably some bugs that were fixed in newer versions.
i
I had just started learning ktor to migrate my android app from firebase. The first ktor course a found by https://www.raywenderlich.com was using ktor 1.4.1. Being a novice i feared tampering with dependencies.😅 I would appreciate it if you helped me restructure to latest.Since there are limited resources. and mentors to it.Thanks
a
Sorry for being out of touch for quite a while. I've updated dependencies in your project. The problem with an empty response is due to the transitive Netty dependency of
com.github.AfricasTalkingLtd.africastalking-java:core
artifact. As a quick workaround, you can use the Jetty engine (this is already fixed in the attached project).
i
Thank you very much. Not every one would be king enough to help. The AfricanTalking depedency its for bulk sms provider just like Twillo but its affordable here in africa and also reliable.