konstruktivnie_jwt_generate_validate
This commit is contained in:
parent
50646861e6
commit
d92f5a2d5d
@ -48,6 +48,9 @@ dependencies {
|
||||
implementation("io.ktor:ktor-server-content-negotiation:2.3.4")
|
||||
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.4")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
|
||||
implementation("com.auth0:java-jwt:4.4.0")
|
||||
implementation("io.ktor:ktor-server-auth:2.3.4")
|
||||
implementation("io.ktor:ktor-server-auth-jwt:2.3.4")
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.example
|
||||
|
||||
|
||||
import com.example.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.server.application.*
|
||||
@ -21,6 +20,12 @@ import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
import kotlinx.serialization.modules.contextual
|
||||
import java.math.BigDecimal
|
||||
import java.util.*
|
||||
import com.auth0.jwt.JWT
|
||||
import com.auth0.jwt.algorithms.Algorithm
|
||||
import io.ktor.server.auth.*
|
||||
import io.ktor.server.auth.jwt.*
|
||||
import io.ktor.server.config.*
|
||||
|
||||
fun main() {
|
||||
embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
|
||||
@ -51,6 +56,27 @@ fun Application.configureSerialization() {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
install(Authentication) {
|
||||
jwt("auth-jwt") {
|
||||
verifier(
|
||||
JWT.require(Algorithm.HMAC256("secret"))
|
||||
.withIssuer("http://localhost:8080")
|
||||
.withAudience("http://localhost:8080/mainWindow") // Должно совпадать
|
||||
.build()
|
||||
)
|
||||
validate { credential ->
|
||||
if (credential.payload.getClaim("email").asString() != "") {
|
||||
JWTPrincipal(credential.payload)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
challenge { _, _ ->
|
||||
call.respond(HttpStatusCode.Unauthorized, "Token is not valid or has expired")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Application.configureRouting() {
|
||||
@ -58,7 +84,7 @@ fun Application.configureRouting() {
|
||||
post("/register") {
|
||||
val request = call.receive<UserRegisterRequest>()
|
||||
if (AuthService.registerUser(request.name, request.email, request.password)) {
|
||||
call.respond(mapOf("message" to "Регистрация успешна"))
|
||||
call.respond(mapOf("Email" to "Успешно"))
|
||||
} else {
|
||||
call.respond(mapOf("error" to "Email уже зарегистрирован"))
|
||||
}
|
||||
@ -66,10 +92,34 @@ fun Application.configureRouting() {
|
||||
|
||||
post("/login") {
|
||||
val request = call.receive<UserLoginRequest>()
|
||||
try {
|
||||
if (AuthService.loginUser(request.email, request.password)) {
|
||||
call.respond(mapOf("message" to "Вход успешен"))
|
||||
} else {
|
||||
call.respond(mapOf("error" to "Неверный email или пароль"))
|
||||
// val jwtSecret = environment.config.propertyOrNull("jwt.secret")?.getString()
|
||||
val jwtSecret = "secret"
|
||||
?: throw ApplicationConfigurationException("jwt.secret not found")
|
||||
log.info("JWT Secret: $jwtSecret")
|
||||
|
||||
// val jwtIssue = environment.config.propertyOrNull("jwt.issue")?.getString()
|
||||
val jwtIssue = "http://localhost:8080"
|
||||
?: throw ApplicationConfigurationException("jwt.issue not found")
|
||||
log.info("JWT Issue: $jwtIssue")
|
||||
|
||||
// val jwtAudience = environment.config.propertyOrNull("jwt.audience")?.getString()
|
||||
val jwtAudience = "http://localhost:8080/mainWindow"
|
||||
?: throw ApplicationConfigurationException("jwt.audience not found")
|
||||
log.info("JWT Audience: $jwtAudience")
|
||||
val token = JWT.create()
|
||||
.withIssuer(jwtIssue)
|
||||
.withAudience(jwtAudience)
|
||||
.withClaim("email", request.email)
|
||||
.withExpiresAt(Date(System.currentTimeMillis() + 10 * 60000))
|
||||
.sign(Algorithm.HMAC256(jwtSecret))
|
||||
|
||||
call.respond(mapOf("Token" to token))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
log.error("Error fetching sneakers: ${e.message}", e)
|
||||
call.respond(HttpStatusCode.InternalServerError, "Error: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,40 +144,29 @@ fun Application.configureRouting() {
|
||||
}
|
||||
}
|
||||
|
||||
post("/reset-passwor") {
|
||||
val request = call.receive<UserResetPasswordRequest>()
|
||||
if (AuthService.resetPassword(request.code, request.newPassword)) {
|
||||
call.respond(mapOf("message" to "Пароль успешно изменён"))
|
||||
} else {
|
||||
call.respond(mapOf("error" to "Неверный код"))
|
||||
}
|
||||
}
|
||||
authenticate("auth-jwt"){
|
||||
get("/mainWindow") {
|
||||
try {
|
||||
val principal = call.principal<JWTPrincipal>()
|
||||
val userEmail = principal?.payload?.getClaim("email")?.asString()
|
||||
|
||||
// get ("/mainWindow"){
|
||||
// val sneakers = AuthService.selectSneakers()
|
||||
// call.respond(mapOf("sneaker" to sneakers))
|
||||
// }
|
||||
if (userEmail == null) {
|
||||
call.respond(HttpStatusCode.Unauthorized, "Invalid token")
|
||||
return@get
|
||||
}
|
||||
|
||||
// get("/mainWindow") {
|
||||
// try {
|
||||
// // Ваш код для обработки запроса
|
||||
// call.respondText("Main Window Content")
|
||||
// } catch (e: Exception) {
|
||||
// call.respond(HttpStatusCode.InternalServerError, "Error: ${e.message}")
|
||||
// }
|
||||
// }
|
||||
log.info("User $userEmail is accessing /mainWindow")
|
||||
|
||||
get("/mainWindow") {
|
||||
try {
|
||||
val sneakers = AuthService.selectSneakers()
|
||||
if (sneakers.isNotEmpty()) {
|
||||
call.respond(mapOf("sneakers" to sneakers))
|
||||
} else {
|
||||
call.respond(mapOf("error" to "No sneakers found"))
|
||||
val sneakers = AuthService.selectSneakers()
|
||||
if (sneakers.isNotEmpty()) {
|
||||
call.respond(mapOf("sneakers" to sneakers))
|
||||
} else {
|
||||
call.respond(mapOf("error" to "No sneakers found"))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
log.error("Error fetching sneakers: ${e.message}", e)
|
||||
call.respond(HttpStatusCode.InternalServerError, "Error: ${e.message}")
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
log.error("Error fetching sneakers: ${e.message}", e)
|
||||
call.respond(HttpStatusCode.InternalServerError, "Error: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,75 +1,3 @@
|
||||
//package com.example
|
||||
//
|
||||
//import at.favre.lib.crypto.bcrypt.BCrypt
|
||||
//import org.jetbrains.exposed.sql.*
|
||||
//import org.jetbrains.exposed.sql.transactions.transaction
|
||||
//import java.util.UUID
|
||||
//
|
||||
//object AuthService {
|
||||
//
|
||||
// fun registerUser(name: String, email: String, password: String): Boolean {
|
||||
// val hashedPassword = hashPassword(password)
|
||||
// return transaction {
|
||||
// if (Users.select { Users.email eq email }.empty()) {
|
||||
// Users.insert {
|
||||
// it[Users.name] = name
|
||||
// it[Users.email] = email
|
||||
// it[Users.passwordHash] = hashedPassword
|
||||
// }
|
||||
// true
|
||||
// } else {
|
||||
// false
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fun loginUser(email: String, password: String): Boolean {
|
||||
// val user = transaction {
|
||||
// Users.select { Users.email eq email }
|
||||
// .mapNotNull { it[Users.passwordHash] }
|
||||
// .firstOrNull()
|
||||
// }
|
||||
// return user != null && checkPassword(password, user)
|
||||
// }
|
||||
//
|
||||
// fun generateResetToken(email: String): String? {
|
||||
// val token = UUID.randomUUID().toString()
|
||||
// return transaction {
|
||||
// val updatedRows = Users.update({ Users.email eq email }) {
|
||||
// it[resetToken] = token
|
||||
// }
|
||||
// if (updatedRows > 0) token else null
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// fun resetPassword(token: String, newPassword: String): Boolean {
|
||||
// return transaction {
|
||||
// val email = Users.select { Users.resetToken eq token }
|
||||
// .mapNotNull { it[Users.email] }
|
||||
// .firstOrNull()
|
||||
//
|
||||
// if (email != null) {
|
||||
// val hashedPassword = hashPassword(newPassword)
|
||||
// Users.update({ Users.email eq email }) {
|
||||
// it[passwordHash] = hashedPassword
|
||||
// it[resetToken] = null
|
||||
// }
|
||||
// true
|
||||
// } else {
|
||||
// false
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private fun hashPassword(password: String): String {
|
||||
// return BCrypt.withDefaults().hashToString(12, password.toCharArray())
|
||||
// }
|
||||
//
|
||||
// private fun checkPassword(password: String, hash: String): Boolean {
|
||||
// return BCrypt.verifyer().verify(password.toCharArray(), hash).verified
|
||||
// }
|
||||
//}
|
||||
|
||||
package com.example
|
||||
|
||||
import at.favre.lib.crypto.bcrypt.BCrypt
|
||||
|
6
src/main/resources/application.conf
Normal file
6
src/main/resources/application.conf
Normal file
@ -0,0 +1,6 @@
|
||||
jwt {
|
||||
secret = "secret"
|
||||
issue = "http://localhost:8080"
|
||||
audience = "http://localhost:8080/test" // временная строка
|
||||
realm = "Access to 'hello'"
|
||||
}
|
Loading…
Reference in New Issue
Block a user