加入登出功能
This commit is contained in:
parent
9237736067
commit
64c987f6c0
@ -12,5 +12,4 @@ fun Application.module() {
|
||||
DatabaseFactory.init()
|
||||
DatabaseFactory.createTable()
|
||||
configureRouting()
|
||||
configureSecurity()
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package com.ray650128.model
|
||||
|
||||
import io.ktor.server.auth.*
|
||||
|
||||
data class User(
|
||||
var id: Long? = -1,
|
||||
var name: String? = "",
|
||||
@ -8,4 +10,4 @@ data class User(
|
||||
var token: String? = "",
|
||||
var createTime: Long? = -1,
|
||||
var updateTime: Long? = -1
|
||||
)
|
||||
): Principal
|
||||
|
||||
@ -2,19 +2,34 @@ package com.ray650128.plugins
|
||||
|
||||
import com.ray650128.model.LoginBody
|
||||
import com.ray650128.model.User
|
||||
import com.ray650128.repository.UserRepository
|
||||
import io.ktor.server.routing.*
|
||||
import com.ray650128.service.UserService
|
||||
import com.ray650128.utils.JwtConfig
|
||||
import io.ktor.http.*
|
||||
import io.ktor.serialization.gson.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.auth.*
|
||||
import io.ktor.server.auth.jwt.*
|
||||
import io.ktor.server.plugins.contentnegotiation.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.request.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
|
||||
fun Application.configureRouting() {
|
||||
|
||||
val userRepository = UserRepository()
|
||||
|
||||
install(Authentication) {
|
||||
jwt {
|
||||
verifier(JwtConfig.verifier)
|
||||
realm = JwtConfig.myRealm
|
||||
validate {
|
||||
val name = it.payload.getClaim("account").asString()
|
||||
if (name != null) {
|
||||
User(account = name, password = "")
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
install(ContentNegotiation) {
|
||||
gson {
|
||||
}
|
||||
@ -26,16 +41,86 @@ fun Application.configureRouting() {
|
||||
}
|
||||
|
||||
post("/api/v1/register") {
|
||||
val body = call.receive<LoginBody>()
|
||||
val token = JwtConfig.generateToken(body)
|
||||
val data = User(
|
||||
account = body.account,
|
||||
password = body.password,
|
||||
token = token
|
||||
)
|
||||
val result = UserService().addUser(data)
|
||||
if (result) {
|
||||
call.respond(
|
||||
status = HttpStatusCode.OK,
|
||||
message = mapOf("token" to token)
|
||||
)
|
||||
} else {
|
||||
call.respond(
|
||||
status = HttpStatusCode.BadRequest,
|
||||
message = mapOf("message" to "User has exist.")
|
||||
)
|
||||
}
|
||||
}
|
||||
post("/api/v1/login") {
|
||||
val body = call.receive<LoginBody>()
|
||||
val data = User(
|
||||
account = body.account,
|
||||
password = body.password
|
||||
)
|
||||
userRepository.add(data)
|
||||
call.respond(
|
||||
status = HttpStatusCode.OK,
|
||||
message = mapOf("token" to "aaaaaaa")
|
||||
)
|
||||
// Check username and password
|
||||
val user = UserService().getUser(data)
|
||||
if (user != null) {
|
||||
var token = user.token
|
||||
if (token.isNullOrEmpty()) {
|
||||
token = JwtConfig.generateToken(body)
|
||||
user.token = token
|
||||
UserService().updateUser(user)
|
||||
}
|
||||
call.respond(
|
||||
status = HttpStatusCode.OK,
|
||||
message = mapOf("token" to token)
|
||||
)
|
||||
} else {
|
||||
call.respond(
|
||||
status = HttpStatusCode.Unauthorized,
|
||||
message = mapOf("message" to "Account or Password wrong.")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
authenticate {
|
||||
post("/api/v1/updateUser") {
|
||||
call.respond(
|
||||
status = HttpStatusCode.OK,
|
||||
message = mapOf("message" to "Test.")
|
||||
)
|
||||
}
|
||||
|
||||
post("/api/v1/logout") {
|
||||
val account = call.authentication.principal<User>()?.account
|
||||
println("[Logout] Account: $account")
|
||||
if (account.isNullOrEmpty()) {
|
||||
call.respond(
|
||||
status = HttpStatusCode.Unauthorized,
|
||||
message = mapOf("message" to "Unauthorized.")
|
||||
)
|
||||
} else {
|
||||
val user = UserService().getUserByAccount(account)
|
||||
if (user != null) {
|
||||
user.token = null
|
||||
UserService().updateUser(user)
|
||||
call.respond(
|
||||
status = HttpStatusCode.OK,
|
||||
message = mapOf("message" to "success.")
|
||||
)
|
||||
} else {
|
||||
call.respond(
|
||||
status = HttpStatusCode.Unauthorized,
|
||||
message = mapOf("message" to "Unauthorized.")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ class UserRepository {
|
||||
Users.insert {
|
||||
it[account] = data.account
|
||||
it[password] = data.password
|
||||
it[token] = data.token
|
||||
it[createTime] = System.currentTimeMillis()
|
||||
it[updateTime] = System.currentTimeMillis()
|
||||
}
|
||||
@ -40,7 +41,18 @@ class UserRepository {
|
||||
return data
|
||||
}
|
||||
|
||||
suspend fun get(userAccount: String): User? {
|
||||
suspend fun get(data: User): User? {
|
||||
return transaction {
|
||||
Users.select {
|
||||
Users.account eq data.account
|
||||
Users.password eq data.password
|
||||
}.mapNotNull {
|
||||
toUser(it)
|
||||
}.singleOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getByAccount(userAccount: String): User? {
|
||||
return transaction {
|
||||
Users.select { Users.account eq userAccount }.mapNotNull {
|
||||
toUser(it)
|
||||
|
||||
@ -7,11 +7,23 @@ class UserService {
|
||||
val userRepository = UserRepository()
|
||||
|
||||
suspend fun addUser(data: User): Boolean {
|
||||
return if (userRepository.get(data.account) == null) {
|
||||
return if (userRepository.get(data) == null) {
|
||||
userRepository.add(data)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getUser(data: User): User? {
|
||||
return userRepository.get(data)
|
||||
}
|
||||
|
||||
suspend fun getUserByAccount(account: String): User? {
|
||||
return userRepository.getByAccount(account)
|
||||
}
|
||||
|
||||
suspend fun updateUser(data: User) {
|
||||
userRepository.update(data)
|
||||
}
|
||||
}
|
||||
36
src/main/kotlin/com/ray650128/utils/JwtConfig.kt
Normal file
36
src/main/kotlin/com/ray650128/utils/JwtConfig.kt
Normal file
@ -0,0 +1,36 @@
|
||||
package com.ray650128.utils
|
||||
|
||||
import com.auth0.jwt.JWT
|
||||
import com.auth0.jwt.JWTVerifier
|
||||
import com.auth0.jwt.algorithms.Algorithm
|
||||
import com.ray650128.model.LoginBody
|
||||
import io.ktor.server.application.*
|
||||
import java.util.*
|
||||
|
||||
object JwtConfig {
|
||||
val secret = "my-secret"
|
||||
val issuer = "com.ray650128"
|
||||
val myRealm = "com.ray650128"
|
||||
private val validityInMs = 36_000_00 * 24 // 1 day
|
||||
private val algorithm = Algorithm.HMAC512(secret)
|
||||
|
||||
val verifier: JWTVerifier = JWT
|
||||
.require(algorithm)
|
||||
.withIssuer(issuer)
|
||||
.build()
|
||||
|
||||
/**
|
||||
* Produce a token for this combination of name and password
|
||||
*/
|
||||
fun generateToken(user: LoginBody): String = JWT.create()
|
||||
.withSubject("Authentication")
|
||||
.withIssuer(issuer)
|
||||
.withClaim("account", user.account)
|
||||
//.withExpiresAt(getExpiration()) // optional
|
||||
.sign(algorithm)
|
||||
|
||||
/**
|
||||
* Calculate the expiration Date based on current time + the given validity
|
||||
*/
|
||||
private fun getExpiration() = Date(System.currentTimeMillis() + validityInMs)
|
||||
}
|
||||
@ -8,7 +8,9 @@ ktor {
|
||||
}
|
||||
}
|
||||
jwt {
|
||||
domain = "https://jwt-provider-domain/"
|
||||
secret = "secret"
|
||||
domain = "https://www.ray650128.com"
|
||||
issuer = "https://www.ray650128.com/"
|
||||
audience = "jwt-audience"
|
||||
realm = "ktor sample app"
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user