hello everyone!
Am building a simple backed and am using Bearer Token for authentication. The problem is that, I want to get response in my postman if the token has expired or its invalid using intercept but I just cant get the response. This is my implementation;
package com.example.routing
import com.example.dao.UsersDao
import com.example.hashing.Sha256Hasher
import com.example.models.User
import com.example.models.UserSignUpRequest
import com.example.models.UserSignUpRequest1
import com.example.schemas.Users
import com.example.service.UserSignUpRequestValidator
import io.konform.validation.Invalid
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.auth.jwt.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.time.Instant
suspend fun ApplicationCall.errorResponse(statusCode: HttpStatusCode, message: String){
respond(statusCode, mapOf("error" to message))
}
fun Application.userRoutes() {
val logger: Logger = LoggerFactory.getLogger(Application::_class_.java)
routing {
authenticate {
route("/api") {
// Add the "intercept ' function at the beginning of the routing block
intercept(ApplicationCallPipeline.Call) {
if (call.request.path().startsWith("/api")) {
// Verify token and check username validity for all routes starting with "/api"
val principal = call.authentication.principal<JWTPrincipal>()
val username = principal?.payload?.getClaim("username")?.asString()
if (username ==
null) {
logger.info("kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk ")
val expirationTime = principal?.payload?.expiresAt?.toInstant()
if (expirationTime !=
null && expirationTime < Instant.now()) {
call.respond(HttpStatusCode.Unauthorized, "Token has expired")
}
else {
call.respond(HttpStatusCode.Unauthorized, "Invalid Token")
}
_return_*@intercept* finish()
}
}
}
get("/getUsers") {
try {
val users = UsersDao().getAllUsers()
call.respond(HttpStatusCode.OK, users)
}
catch (exception:
Exception) {
call.errorResponse(HttpStatusCode.Unauthorized," Invalid Request : ${exception.message}")
}
}
post("users/registerUser") {
val request = call.receive<UserSignUpRequest1>()
val validationResult = UserSignUpRequestValidator.validate(request)
if (validationResult
is Invalid) {
val validateErrors = validationResult.errors
val response = mapOf("Errors" to validateErrors)
call.respond(HttpStatusCode.BadRequest, response)
_return_
@post
}
val username = request.username
if (username.isNotEmpty()) {
val userExists = UsersDao().checkIfUserExistsByUsername(username)
if (userExists) {
val response = mapOf("exists" to "Record with username $username already exists")
call.respond(HttpStatusCode.Conflict, response)
_return_
@post
}
}
//Hash the password
val password = request.password
val hashedPassword = Sha256Hasher().createHashText(password)
//create a new Request with the hashed password
val requestWithHashedPassword = request.copy(password = hashedPassword)
val userId = UsersDao().createUser(requestWithHashedPassword)
if (userId > 0) {
UsersDao().saveUserDetails(request, userId)
call.respond(call.respond(HttpStatusCode.OK, "User Registration Successful with ID $userId"))
}
}
get("/users/{userId}") {
val userId = call.parameters["userId"]?.toIntOrNull()
if (userId !=
null) {
val principal = call.authentication.principal<JWTPrincipal>()
val username = principal?.payload?.getClaim("username")?.asString()
if (username !=
null && UsersDao().validateUser(username, userId)) {
val user = UsersDao().getUser(userId)
call.respond(HttpStatusCode.OK, user ?: HttpStatusCode.NotFound)
}
else {
call.respond(HttpStatusCode.Unauthorized, "Invalid Token")
}
}
else {
call.respond(HttpStatusCode.BadRequest, "Null values are not allowed")
}
}
}
}
}
}
and this is my plugin validation
un Application.configureSecurity() {
// Please read the jwt property from the config file if you are using EngineMain
val jwtAudience = JwtConstants.AUDIENCE
val jwtDomain = JwtConstants.DOMAIN
val jwtRealm = JwtConstants.REALM
val secretKeyRedisKey = "secretKey"
val jwtSecret = RedisDao.getValueAsString(secretKeyRedisKey)
authentication {
jwt {
realm = jwtRealm
verifier(
JWT
.require(
Algorithm.HMAC256(jwtSecret))
.withAudience(jwtAudience)
.withIssuer(jwtDomain)
.build()
)
validate { credential ->
if (credential.payload.audience.contains(jwtAudience)) JWTPrincipal(credential.payload)
else null
}
}
}
am wondering what could be the problem