mirror of
https://github.com/dalbodeule/chibot-chzzk-bot.git
synced 2025-08-08 05:11:12 +00:00
add OAuth flows
- add naver OAuth flow
This commit is contained in:
@@ -1,21 +1,38 @@
|
||||
package space.mori.chzzk_bot.webserver
|
||||
|
||||
import applicationHttpClient
|
||||
import io.github.cdimascio.dotenv.dotenv
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.serialization.kotlinx.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.auth.*
|
||||
import io.ktor.server.engine.*
|
||||
import io.ktor.server.netty.*
|
||||
import io.ktor.server.plugins.contentnegotiation.*
|
||||
import io.ktor.server.plugins.cors.routing.*
|
||||
import io.ktor.server.plugins.swagger.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import io.ktor.server.sessions.*
|
||||
import io.ktor.server.websocket.*
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import space.mori.chzzk_bot.common.dotenv
|
||||
import space.mori.chzzk_bot.webserver.routes.*
|
||||
import java.time.Duration
|
||||
|
||||
val server = embeddedServer(Netty, port = 8080) {
|
||||
val dotenv = dotenv {
|
||||
ignoreIfMissing = true
|
||||
}
|
||||
|
||||
const val naverMeAPIURL = "https://openapi.naver.com/v1/nid/me"
|
||||
|
||||
val redirects = mutableMapOf<String, String>()
|
||||
|
||||
val server = embeddedServer(Netty, port = 8080, ) {
|
||||
install(WebSockets) {
|
||||
pingPeriod = Duration.ofSeconds(15)
|
||||
timeout = Duration.ofSeconds(15)
|
||||
@@ -34,7 +51,66 @@ val server = embeddedServer(Netty, port = 8080) {
|
||||
anyHost()
|
||||
allowHeader(HttpHeaders.ContentType)
|
||||
}
|
||||
install(Sessions) {
|
||||
cookie<UserSession>("user_session", storage = SessionStorageMemory()) {}
|
||||
}
|
||||
install(Authentication) {
|
||||
oauth("auth-oauth-naver") {
|
||||
urlProvider = { "${dotenv["HOST"]}/auth/callback" }
|
||||
providerLookup = { OAuthServerSettings.OAuth2ServerSettings(
|
||||
name = "naver",
|
||||
authorizeUrl = "https://nid.naver.com/oauth2.0/authorize",
|
||||
accessTokenUrl = "https://nid.naver.com/oauth2.0/token",
|
||||
requestMethod = HttpMethod.Post,
|
||||
clientId = dotenv["NAVER_CLIENT_ID"],
|
||||
clientSecret = dotenv["NAVER_CLIENT_SECRET"],
|
||||
defaultScopes = listOf(""),
|
||||
extraAuthParameters = listOf(),
|
||||
onStateCreated = { call, state ->
|
||||
//saves new state with redirect url value
|
||||
call.request.queryParameters["redirectUrl"]?.let {
|
||||
redirects[state] = it
|
||||
}
|
||||
}
|
||||
)}
|
||||
client = applicationHttpClient
|
||||
}
|
||||
}
|
||||
routing {
|
||||
route("/auth") {
|
||||
authenticate("auth-oauth-naver") {
|
||||
get("/login") {
|
||||
|
||||
}
|
||||
get("/callback") {
|
||||
val currentPrincipal = call.principal<OAuthAccessTokenResponse.OAuth2>()
|
||||
currentPrincipal?.let { principal ->
|
||||
principal.state?.let { state ->
|
||||
val userInfo: NaverAPI<NaverMeAPI> = applicationHttpClient.get(naverMeAPIURL) {
|
||||
headers{
|
||||
append(HttpHeaders.Authorization, "Bearer ${principal.accessToken}")
|
||||
}
|
||||
}.body()
|
||||
|
||||
call.sessions.set(userInfo.response?.let { it1 ->
|
||||
UserSession(state,
|
||||
it1.id, it1.nickname, it1.profile_image)
|
||||
})
|
||||
|
||||
redirects[state]?.let { redirect ->
|
||||
call.respondRedirect(redirect)
|
||||
return@get
|
||||
}
|
||||
}
|
||||
}
|
||||
call.respondRedirect(dotenv["FRONTEND"])
|
||||
}
|
||||
}
|
||||
get("/logout") {
|
||||
call.sessions.clear<UserSession>()
|
||||
}
|
||||
}
|
||||
|
||||
apiRoutes()
|
||||
apiSongRoutes()
|
||||
wsTimerRoutes()
|
||||
@@ -54,4 +130,22 @@ fun start() {
|
||||
|
||||
fun stop() {
|
||||
server.stop()
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
data class UserSession(
|
||||
val state: String,
|
||||
val id: String,
|
||||
val nickname: String,
|
||||
val profileImage: String
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class NaverMeAPI(
|
||||
val id: String,
|
||||
val nickname: String,
|
||||
val profile_image: String
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class NaverAPI<T>(val resultcode: String, val message: String, val response: T?)
|
@@ -0,0 +1,10 @@
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.engine.cio.*
|
||||
import io.ktor.client.plugins.contentnegotiation.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
|
||||
val applicationHttpClient = HttpClient(CIO) {
|
||||
install(ContentNegotiation) {
|
||||
json()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user