Authentication Plugins: JWT and Session
Secure Ktor routes using JWT bearer tokens and session-based authentication.
Authentication Plugins: JWT and Session is a free Kotlin Academy lesson on CoddyKit. This is lesson 4 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the Kotlin Academy learning path, and your progress syncs across the web and the CoddyKit app. The Kotlin Academy course includes 4 lessons in total.
Ktor Authentication Overview
Ktor's Authentication plugin provides a unified API for protecting routes. You configure one or more providers (JWT, Session, Basic, OAuth, etc.) and then wrap routes in an authenticate("providerName") { } block.
Adding Auth Dependencies
Add the auth and JWT libraries to your build:
dependencies {
implementation("io.ktor:ktor-server-auth:2.3.12")
implementation("io.ktor:ktor-server-auth-jwt:2.3.12")
implementation("io.ktor:ktor-server-sessions:2.3.12")
}Configuring JWT Authentication
Install the Authentication plugin and configure a JWT provider. The verifier validates the token signature; validate extracts the principal from the payload:
install(Authentication) {
jwt("auth-jwt") {
realm = "ktor app"
verifier(
JWT.require(Algorithm.HMAC256(secret))
.withAudience(audience)
.withIssuer(issuer)
.build()
)
validate { credential ->
if (credential.payload.getClaim("username").asString() != null)
JWTPrincipal(credential.payload)
else null
}
}
}Protecting Routes with JWT
Wrap any route group in authenticate("auth-jwt") { }. Unauthenticated requests receive a 401 automatically:
routing {
authenticate("auth-jwt") {
get("/protected") {
val principal = call.principal<JWTPrincipal>()!!
val username = principal.payload.getClaim("username").asString()
call.respondText("Hello, $username")
}
}
}Issuing a JWT Token
Generate and sign a JWT on the login endpoint using the java-jwt library:
post("/login") {
val user = call.receive<LoginRequest>()
// validate credentials ...
val token = JWT.create()
.withAudience(audience)
.withIssuer(issuer)
.withClaim("username", user.username)
.withExpiresAt(Date(System.currentTimeMillis() + 3_600_000))
.sign(Algorithm.HMAC256(secret))
call.respond(mapOf("token" to token))
}Session Authentication
Sessions store user state server-side (or client-side as signed cookies). Install the Sessions plugin and define a session data class:
data class UserSession(val userId: Long, val username: String)
install(Sessions) {
cookie<UserSession>("user_session") {
cookie.path = "/"
cookie.httpOnly = true
}
}Configuring Session Auth Provider
Create a session authentication provider that reads the session and returns a principal:
install(Authentication) {
session<UserSession>("auth-session") {
validate { session -> session }
challenge { call.respond(HttpStatusCode.Unauthorized) }
}
}Setting and Clearing Sessions
Set a session after login with call.sessions.set() and clear it on logout with call.sessions.clear:
post("/login") {
val creds = call.receive<LoginRequest>()
// validate ...
call.sessions.set(UserSession(userId = 1L, username = creds.username))
call.respond(HttpStatusCode.OK)
}
post("/logout") {
call.sessions.clear<UserSession>()
call.respond(HttpStatusCode.OK)
}JWT vs Session: When to Use Each
JWT: stateless, good for APIs consumed by mobile/SPA clients. Token carries all claims; server needs no session store. Sessions: stateful, good for server-rendered web apps. Session ID in cookie; server holds the data (memory, Redis, DB).
Combining Multiple Auth Providers
You can define multiple providers and require any of them using authenticate("jwt", "session") { }. Ktor tries each in order and accepts the request if any provider validates successfully.
Custom Challenge Responses
Each provider has a challenge block that defines what to do when authentication fails. Return a 401 with a JSON error body instead of the default WWW-Authenticate header:
jwt("auth-jwt") {
// ...
challenge { _, _ ->
call.respond(HttpStatusCode.Unauthorized, mapOf("error" to "Token expired or invalid"))
}
}Quick Check
What does the validate block in a Ktor JWT provider do?
Recap: Authentication Plugins — JWT and Session
Key takeaways:
- Install
Authentication; configure providers (jwt, session, basic, oauth) - Protect routes with
authenticate("providerName") { } - JWT: stateless tokens; sign on login, verify with
verifier, read claims invalidate - Sessions: stateful;
call.sessions.set()on login,clear()on logout - Use
challengeto customize the 401 response format
Learn Kotlin with an AI tutor — free
Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.
- Courses
- 51
- Lessons
- 203
Frequently Asked Questions
Is the “Authentication Plugins: JWT and Session” lesson free?
Yes — any 3 lessons of the Kotlin Academy learning path, including “Authentication Plugins: JWT and Session”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The Kotlin Academy course includes 4 lessons in total.
What will I learn in “Authentication Plugins: JWT and Session”?
Secure Ktor routes using JWT bearer tokens and session-based authentication. You practise Kotlin Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Kotlin Academy?
No prior experience is required. Kotlin Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.
How long does the “Authentication Plugins: JWT and Session” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Kotlin Academy lesson?
Yes. Every Kotlin Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Ktor Project Setup: embeddedServer and Application Modules
- Routing and Typed Parameters
- Content Negotiation and kotlinx.serialization
- Authentication Plugins: JWT and Session