面试题答案
一键面试- 添加依赖:
在
build.gradle.kts
文件中添加Ktor和JWT相关依赖:dependencies { implementation("io.ktor:ktor-server-core:2.3.2") implementation("io.ktor:ktor-server-auth:2.3.2") implementation("io.ktor:ktor-server-auth-jwt:2.3.2") implementation("io.jsonwebtoken:jjwt-api:0.11.2") runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.2") runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.2") }
- 配置JWT认证:
在
Application.kt
中配置JWT认证:
解释:import io.ktor.server.auth.* import io.ktor.server.auth.jwt.* import io.jsonwebtoken.Claims import io.jsonwebtoken.Jwts import io.jsonwebtoken.SignatureAlgorithm import io.jsonwebtoken.security.Keys val key = Keys.secretKeyFor(SignatureAlgorithm.HS256) val issuer = "yourIssuer" fun Application.configureJwtAuth() { install(Authentication) { jwt { verifier(Jwts.parserBuilder() .setSigningKey(key) .requireIssuer(issuer) .build()) validate { credential -> if (credential.payload.getSubject()!= null) { JWTPrincipal(credential.payload) } else { null } } } } }
- 首先生成一个用于签名的密钥
key
和设置发行人issuer
。 install(Authentication)
安装认证模块。jwt
配置JWT认证,verifier
用于验证JWT的签名和发行人等信息,validate
用于验证JWT的负载内容,确保subject
不为空并返回JWTPrincipal
。
- 首先生成一个用于签名的密钥
- 生成JWT:
生成JWT的函数示例:
解释:fun generateJwtToken(subject: String, roles: List<String>): String { val claims = Claims() claims["roles"] = roles return Jwts.builder() .setSubject(subject) .setIssuer(issuer) .setClaims(claims) .signWith(key, SignatureAlgorithm.HS256) .compact() }
- 此函数接受
subject
(通常是用户名等标识)和roles
(用户角色列表)。 - 在
Claims
中设置roles
,然后构建JWT,设置发行人、主题,签名并返回紧凑的JWT字符串。
- 此函数接受
- 基于角色的授权:
配置路由并进行基于角色的授权:
解释:fun Application.configureRouting() { configureJwtAuth() routing { authenticate { get("/admin-only") { val principal = call.principal<JWTPrincipal>() val roles = principal?.getClaim("roles", List::class.java) as? List<String> if (roles?.contains("admin") == true) { call.respondText("This is an admin - only endpoint.") } else { call.respond(HttpStatusCode.Forbidden, "You are not authorized to access this endpoint.") } } } } }
authenticate
确保请求带有有效的JWT。- 在
/admin - only
路由中,获取JWT的principal
,从principal
中提取roles
。 - 如果
roles
中包含admin
,则允许访问并返回相应信息;否则返回403 Forbidden
错误。