移除FreeMarker
This commit is contained in:
parent
df2b630175
commit
a361978101
@ -23,12 +23,11 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("io.ktor:ktor-server-core-jvm:$ktor_version")
|
implementation("io.ktor:ktor-server-core-jvm:$ktor_version")
|
||||||
|
implementation("io.ktor:ktor-server-cors:$ktor_version")
|
||||||
implementation("io.ktor:ktor-server-auth-jvm:$ktor_version")
|
implementation("io.ktor:ktor-server-auth-jvm:$ktor_version")
|
||||||
implementation("io.ktor:ktor-server-auth-jwt-jvm:$ktor_version")
|
implementation("io.ktor:ktor-server-auth-jwt-jvm:$ktor_version")
|
||||||
implementation("io.ktor:ktor-server-sessions-jvm:$ktor_version")
|
|
||||||
implementation("io.ktor:ktor-server-content-negotiation-jvm:$ktor_version")
|
implementation("io.ktor:ktor-server-content-negotiation-jvm:$ktor_version")
|
||||||
implementation("io.ktor:ktor-serialization-gson-jvm:$ktor_version")
|
implementation("io.ktor:ktor-serialization-gson-jvm:$ktor_version")
|
||||||
implementation("io.ktor:ktor-server-freemarker-jvm:$ktor_version")
|
|
||||||
implementation("io.ktor:ktor-server-netty-jvm:$ktor_version")
|
implementation("io.ktor:ktor-server-netty-jvm:$ktor_version")
|
||||||
implementation("ch.qos.logback:logback-classic:$logback_version")
|
implementation("ch.qos.logback:logback-classic:$logback_version")
|
||||||
testImplementation("io.ktor:ktor-server-tests-jvm:$ktor_version")
|
testImplementation("io.ktor:ktor-server-tests-jvm:$ktor_version")
|
||||||
|
|||||||
@ -2,6 +2,8 @@ package com.ray650128
|
|||||||
|
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
import com.ray650128.plugins.*
|
import com.ray650128.plugins.*
|
||||||
|
import java.security.MessageDigest
|
||||||
|
import java.security.NoSuchAlgorithmException
|
||||||
|
|
||||||
fun main(args: Array<String>): Unit =
|
fun main(args: Array<String>): Unit =
|
||||||
io.ktor.server.netty.EngineMain.main(args)
|
io.ktor.server.netty.EngineMain.main(args)
|
||||||
@ -10,6 +12,27 @@ fun main(args: Array<String>): Unit =
|
|||||||
fun Application.module() {
|
fun Application.module() {
|
||||||
configureSecurity()
|
configureSecurity()
|
||||||
configureSerialization()
|
configureSerialization()
|
||||||
configureTemplating()
|
|
||||||
configureRouting()
|
configureRouting()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun md5encode(password: String): String {
|
||||||
|
try {
|
||||||
|
val instance: MessageDigest = MessageDigest.getInstance("MD5") // 獲取md5加密對象
|
||||||
|
val digest:ByteArray = instance.digest(password.toByteArray()) // 對字串加密,返回字節數組
|
||||||
|
val sb = StringBuffer()
|
||||||
|
for (b in digest) {
|
||||||
|
val i :Int = b.toInt() and 0xff // 獲取低八位有效值
|
||||||
|
var hexString = Integer.toHexString(i) // 將整數轉化爲16進制
|
||||||
|
if (hexString.length < 2) {
|
||||||
|
hexString = "0$hexString" // 如果是一位的話,補0
|
||||||
|
}
|
||||||
|
sb.append(hexString)
|
||||||
|
}
|
||||||
|
return sb.toString()
|
||||||
|
|
||||||
|
} catch (e: NoSuchAlgorithmException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|||||||
@ -7,16 +7,17 @@ import com.ray650128.model.User
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
object JwtConfig {
|
object JwtConfig {
|
||||||
val secret = "my-secret"
|
val jwtAudience = "jwt-audience"
|
||||||
val issuer = "com.ray650128"
|
val jwtDomain = "com.ray650128"
|
||||||
val myRealm = "com.ray650128"
|
val jwtRealm = "pc re:dive rank table"
|
||||||
|
val jwtSecret = "secret"
|
||||||
//private val validityInMs = 36_000_00 * 24 // 1 day
|
//private val validityInMs = 36_000_00 * 24 // 1 day
|
||||||
private val validityInMs = 300000 // 5 min
|
private const val validityInMs = 300000 // 5 min
|
||||||
private val algorithm = Algorithm.HMAC512(secret)
|
private val algorithm = Algorithm.HMAC512(jwtSecret)
|
||||||
|
|
||||||
val verifier: JWTVerifier = JWT
|
val verifier: JWTVerifier = JWT
|
||||||
.require(algorithm)
|
.require(algorithm)
|
||||||
.withIssuer(issuer)
|
.withIssuer(jwtDomain)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,7 +25,7 @@ object JwtConfig {
|
|||||||
*/
|
*/
|
||||||
fun generateToken(user: User): String = JWT.create()
|
fun generateToken(user: User): String = JWT.create()
|
||||||
.withSubject("Authentication")
|
.withSubject("Authentication")
|
||||||
.withIssuer(issuer)
|
.withIssuer(jwtDomain)
|
||||||
.withClaim("account", user.account)
|
.withClaim("account", user.account)
|
||||||
.withExpiresAt(getExpiration()) // optional
|
.withExpiresAt(getExpiration()) // optional
|
||||||
.sign(algorithm)
|
.sign(algorithm)
|
||||||
|
|||||||
@ -1,21 +1,38 @@
|
|||||||
package com.ray650128.plugins
|
package com.ray650128.plugins
|
||||||
|
|
||||||
import com.ray650128.JwtConfig
|
import com.ray650128.JwtConfig
|
||||||
import com.ray650128.extensions.sendBadRequest
|
import com.ray650128.extensions.*
|
||||||
import com.ray650128.extensions.sendCreated
|
import com.ray650128.md5encode
|
||||||
import com.ray650128.extensions.sendSuccess
|
|
||||||
import com.ray650128.extensions.sendUnauthorized
|
|
||||||
import com.ray650128.model.ErrorResponse
|
import com.ray650128.model.ErrorResponse
|
||||||
import com.ray650128.model.LoginResult
|
import com.ray650128.model.LoginResult
|
||||||
import com.ray650128.model.User
|
import com.ray650128.model.User
|
||||||
import com.ray650128.service.UserService
|
import com.ray650128.service.UserService
|
||||||
|
import io.ktor.http.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
import io.ktor.server.auth.*
|
import io.ktor.server.auth.*
|
||||||
|
import io.ktor.server.plugins.cors.routing.*
|
||||||
import io.ktor.server.request.*
|
import io.ktor.server.request.*
|
||||||
|
import io.ktor.server.response.*
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
fun Application.configureRouting() {
|
fun Application.configureRouting() {
|
||||||
|
|
||||||
|
install(CORS) {
|
||||||
|
allowHeader(HttpHeaders.AccessControlAllowOrigin)
|
||||||
|
allowHeader(HttpHeaders.Accept)
|
||||||
|
allowHeader(HttpHeaders.ContentType)
|
||||||
|
anyHost()
|
||||||
|
allowMethod(HttpMethod.Options)
|
||||||
|
allowMethod(HttpMethod.Get)
|
||||||
|
allowMethod(HttpMethod.Post)
|
||||||
|
allowMethod(HttpMethod.Put)
|
||||||
|
allowMethod(HttpMethod.Delete)
|
||||||
|
allowHeader(HttpHeaders.Authorization)
|
||||||
|
allowCredentials = true
|
||||||
|
allowNonSimpleContentTypes = true
|
||||||
|
}
|
||||||
|
|
||||||
routing {
|
routing {
|
||||||
route("/api") {
|
route("/api") {
|
||||||
route("/v1") {
|
route("/v1") {
|
||||||
@ -26,9 +43,11 @@ fun Application.configureRouting() {
|
|||||||
return@post
|
return@post
|
||||||
}
|
}
|
||||||
val newToken = JwtConfig.generateToken(request)
|
val newToken = JwtConfig.generateToken(request)
|
||||||
val user = request.apply {
|
val user = User(
|
||||||
|
account = request.account,
|
||||||
|
password = md5encode(request.password),
|
||||||
createAt = System.currentTimeMillis()
|
createAt = System.currentTimeMillis()
|
||||||
}
|
)
|
||||||
UserService.create(user)?.let { userId ->
|
UserService.create(user)?.let { userId ->
|
||||||
call.response.headers.append("My-User-Id-Header", userId.toString())
|
call.response.headers.append("My-User-Id-Header", userId.toString())
|
||||||
call.sendCreated(LoginResult(request.account, newToken))
|
call.sendCreated(LoginResult(request.account, newToken))
|
||||||
@ -37,12 +56,13 @@ fun Application.configureRouting() {
|
|||||||
|
|
||||||
post("/login") {
|
post("/login") {
|
||||||
val request = call.receive<User>()
|
val request = call.receive<User>()
|
||||||
val user = UserService.findByLoginInfo(request.account, request.password)
|
val password = md5encode(request.password)
|
||||||
|
val user = UserService.findByLoginInfo(request.account, password)
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
val token = JwtConfig.generateToken(request)
|
val token = JwtConfig.generateToken(request)
|
||||||
call.sendSuccess(LoginResult(request.account, token))
|
call.sendSuccess(LoginResult(request.account, token))
|
||||||
} else {
|
} else {
|
||||||
call.sendBadRequest(ErrorResponse("Account or Password wrong."))
|
call.sendUnauthorized()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import io.ktor.server.auth.*
|
|||||||
import io.ktor.server.auth.jwt.*
|
import io.ktor.server.auth.jwt.*
|
||||||
import com.auth0.jwt.JWT
|
import com.auth0.jwt.JWT
|
||||||
import com.auth0.jwt.algorithms.Algorithm
|
import com.auth0.jwt.algorithms.Algorithm
|
||||||
|
import com.ray650128.JwtConfig
|
||||||
import io.ktor.server.sessions.*
|
import io.ktor.server.sessions.*
|
||||||
import io.ktor.server.response.*
|
import io.ktor.server.response.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
@ -11,37 +12,15 @@ import io.ktor.server.routing.*
|
|||||||
|
|
||||||
fun Application.configureSecurity() {
|
fun Application.configureSecurity() {
|
||||||
|
|
||||||
// Please read the jwt property from the config file if you are using EngineMain
|
|
||||||
val jwtAudience = "jwt-audience"
|
|
||||||
val jwtDomain = "https://jwt-provider-domain/"
|
|
||||||
val jwtRealm = "ktor sample app"
|
|
||||||
val jwtSecret = "secret"
|
|
||||||
authentication {
|
authentication {
|
||||||
jwt {
|
jwt {
|
||||||
realm = jwtRealm
|
realm = JwtConfig.jwtRealm
|
||||||
verifier(
|
verifier(JwtConfig.verifier)
|
||||||
JWT
|
|
||||||
.require(Algorithm.HMAC256(jwtSecret))
|
|
||||||
.withAudience(jwtAudience)
|
|
||||||
.withIssuer(jwtDomain)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
validate { credential ->
|
validate { credential ->
|
||||||
if (credential.payload.audience.contains(jwtAudience)) JWTPrincipal(credential.payload) else null
|
if (credential.payload.audience.contains(JwtConfig.jwtAudience)) {
|
||||||
|
JWTPrincipal(credential.payload)
|
||||||
|
} else null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data class MySession(val count: Int = 0)
|
|
||||||
install(Sessions) {
|
|
||||||
cookie<MySession>("MY_SESSION") {
|
|
||||||
cookie.extensions["SameSite"] = "lax"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
routing {
|
|
||||||
get("/session/increment") {
|
|
||||||
val session = call.sessions.get<MySession>() ?: MySession()
|
|
||||||
call.sessions.set(session.copy(count = session.count + 1))
|
|
||||||
call.respondText("Counter is ${session.count}. Refresh to increment.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +0,0 @@
|
|||||||
package com.ray650128.plugins
|
|
||||||
|
|
||||||
import freemarker.cache.*
|
|
||||||
import io.ktor.server.freemarker.*
|
|
||||||
import io.ktor.server.response.*
|
|
||||||
import io.ktor.server.application.*
|
|
||||||
import io.ktor.server.routing.*
|
|
||||||
|
|
||||||
fun Application.configureTemplating() {
|
|
||||||
install(FreeMarker) {
|
|
||||||
templateLoader = ClassTemplateLoader(this::class.java.classLoader, "templates")
|
|
||||||
}
|
|
||||||
routing {
|
|
||||||
get("/html-freemarker") {
|
|
||||||
call.respond(FreeMarkerContent("index.ftl", mapOf("data" to IndexData(listOf(1, 2, 3))), ""))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data class IndexData(val items: List<Int>)
|
|
||||||
@ -7,8 +7,3 @@ ktor {
|
|||||||
modules = [ com.ray650128.ApplicationKt.module ]
|
modules = [ com.ray650128.ApplicationKt.module ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jwt {
|
|
||||||
domain = "https://jwt-provider-domain/"
|
|
||||||
audience = "jwt-audience"
|
|
||||||
realm = "ktor sample app"
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
<html>
|
|
||||||
<body>
|
|
||||||
<h1>Items:</h1>
|
|
||||||
<#list data.items as item>
|
|
||||||
<h2>The item at index ${item?index} is ${item}</h2>
|
|
||||||
</#list>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Loading…
Reference in New Issue
Block a user