Ktor 全栈之路 (5):JWT 认证全流程实战 —— 打造安全通信闭环

0 阅读2分钟

前言

如果一个后端 API 没有任何认证,那它在互联网上就是裸奔。

对于全栈项目来说,最流行的认证方案莫过于 JWT (JSON Web Token)。它的优势在于“无状态”,服务器不需要存储 Session,非常适合 KMP 这种跨多个端(Android, iOS, Web)的场景。

今天我们就来手把手实现在 Ktor 中搭建 JWT 认证防线。


一、 JWT 的三驾马车

  1. Header:类型和加密算法。
  2. Payload:存放用户信息(如 userId, username)和过期时间。
  3. Signature:服务器私钥签名,防止篡改。

二、 后端实战:配置 JWT 校验

首先,在 Ktor 中安装认证插件:

install(Authentication) {
    jwt("auth-jwt") {
        realm = "Access to 'protected' routes"
        verifier(
            JWT.require(Algorithm.HMAC256("secret-key"))
                .withAudience("my-audience")
                .withIssuer("my-issuer")
                .build()
        )
        validate { credential ->
            if (credential.payload.getClaim("username").asString() != "") {
                JWTPrincipal(credential.payload)
            } else {
                null
            }
        }
    }
}

三、 实战:受保护的路由

配置好后,你可以通过 authenticate 块来保护特定的 API:

routing {
    // 登录接口:公开访问,返回 Token
    post("/login") {
        val user = call.receive<LoginRequest>()
        val token = generateToken(user) // 生成 JWT
        call.respond(mapOf("token" to token))
    }

    // 个人资料接口:必须带 Token 才能访问
    authenticate("auth-jwt") {
        get("/profile") {
            val principal = call.principal<JWTPrincipal>()
            val username = principal!!.payload.getClaim("username").asString()
            call.respondText("Welcome, $username!")
        }
    }
}

四、 全栈闭环:App 侧的 Token 存储

作为资深 Android 开发,你不仅要写后端,还要考虑 App 怎么存:

  1. 安全存储:Android 用 EncryptedSharedPreferences,iOS 用 Keychain
  2. 自动注入:利用 Ktor Client 的 Auth 插件,在每次发请求时自动在 Header 中加上 Authorization: Bearer <token>

五、 安全建议

  1. 绝不在 Payload 中存敏感信息:记住,JWT 的 Payload 只是 Base64 编码,任何人都可以解码看里面的内容。它防的是篡改,不防偷看。不要把用户密码、手机号放进去。
  2. 使用 Refresh Token 机制:Access Token 设置短寿命(如 1 小时),Refresh Token 设置长寿命(如 30 天)。这能极大提升安全性。
  3. 私钥管理secret-key 绝对不能写死在代码里!生产环境必须通过环境变量或 AWS Secrets Manager 获取。

结语

掌握了 JWT,你就打通了前后端信任的“最后一公里”。你的 Ktor 后端现在已经具备了初步的商用安全性。

下一篇是大结局:Ktor 生产级调优:HTTPS、限流与监控