In scala using akka http how can i configure jwt for database like how can i fetch specific username and password from database (mongodb)for generating token, i have done using simple map but for real database what can i do ?? im using spray json please help me out … if possible please send me some code for reference …
package part3.highlevelserver
import java.util.concurrent.TimeUnit
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model.{HttpResponse, StatusCodes}
import akka.http.scaladsl.model.headers.RawHeader
import akka.stream.ActorMaterializer
import akka.http.scaladsl.server.Directives._
import pdi.jwt.{JwtAlgorithm, JwtClaim, JwtSprayJson}
import spray.json._
import scala.util.{Failure, Success}
object SecurityDomain extends DefaultJsonProtocol {
case class LoginRequest(username:String,password:String)
implicit val loginFormat=jsonFormat2(LoginRequest)
}
object JwtAuthorization extends App with SprayJsonSupport {
implicit val system=ActorSystem("Jwt")
implicit val materializer=ActorMaterializer
import system.dispatcher
import SecurityDomain._
val superSecretpasswordDb=Map(
"admin" -> "admin",
"niraj" -> "babaHere"
)
val algorithm=JwtAlgorithm.HS256
val secretKey="topsecret"
def checkPassword(username: String, password: String):Boolean=
superSecretpasswordDb.contains(username) && superSecretpasswordDb(username)==password
def createToken(username: String, expirationPeriodInDays: Int):String= {
val claims=JwtClaim(
expiration = Some(System.currentTimeMillis()/1000 + TimeUnit.DAYS.toSeconds(expirationPeriodInDays)),
issuedAt = Some(System.currentTimeMillis()/1000),
issuer = Some("baba.com"),
)
JwtSprayJson.encode(claims,secretKey,algorithm) //jwt string
}
def isTokenExpired(token:String):Boolean= JwtSprayJson.decode(token,secretKey,Seq(algorithm)) match {
case Success(claims) =>claims.expiration.getOrElse(0L) < System.currentTimeMillis()/1000
case Failure (_) =>true
}
def isTokenValid(token:String):Boolean= JwtSprayJson.isValid(token,secretKey,Seq(algorithm))
val loginRoute=
post{
entity(as[LoginRequest]){
case LoginRequest(username,password) if checkPassword(username,password)=>
val token=createToken(username,1)
respondWithHeader(RawHeader("Access-Token",token)){
complete(StatusCodes.OK)
}
case _ =>complete(StatusCodes.Unauthorized)
}
}
val authenticated=
(path("secureEndPoint") & get){
optionalHeaderValueByName("Authorization"){
case Some(token) =>if (isTokenValid(token)) {
if (isTokenExpired(token)) {
complete(HttpResponse(status = StatusCodes.Unauthorized, entity = "Token expired."))
} else {
complete("User accessed authorized endpoint!")
}
} else {
complete(HttpResponse(status = StatusCodes.Unauthorized, entity = "Token is invalid, or has been tampered with."))
}
case _ => complete(HttpResponse(status = StatusCodes.Unauthorized, entity = "No token provided!"))
}
}
val route=loginRoute ~ authenticated
Http().newServerAt("localhost",8080).bind(route)
}
i have done this using map for username and password but what can i do for database like real database in mongodb…