mirror of
https://github.com/dalbodeule/chibot-chzzk-bot.git
synced 2025-06-08 14:58:21 +00:00
add OAuth flows
- add naver OAuth flow
This commit is contained in:
parent
2f5c4293c0
commit
a828e23767
4
inc.env
4
inc.env
@ -6,5 +6,9 @@ DB_PASS=chzzk
|
||||
RUN_AGENT=false
|
||||
YOUTUBE_API_KEY=
|
||||
RAPID_KEY=
|
||||
HOST=http://localhost:8080
|
||||
FRONTEND=http://localhost:3000
|
||||
NAVER_CLIENT_ID=
|
||||
NAVER_CLIENT_SECRET=
|
||||
NID_AUT=
|
||||
NID_SES=
|
@ -18,9 +18,14 @@ dependencies {
|
||||
implementation("io.ktor:ktor-server-websockets:$ktorVersion")
|
||||
implementation("io.ktor:ktor-server-swagger:$ktorVersion")
|
||||
implementation("io.ktor:ktor-server-content-negotiation:$ktorVersion")
|
||||
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
|
||||
implementation("io.ktor:ktor-server-cors:$ktorVersion")
|
||||
implementation("io.ktor:ktor-server-swagger:$ktorVersion")
|
||||
implementation("io.ktor:ktor-server-auth:$ktorVersion")
|
||||
|
||||
implementation("io.ktor:ktor-client-core:$ktorVersion")
|
||||
implementation("io.ktor:ktor-client-cio:$ktorVersion")
|
||||
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
|
||||
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
|
||||
|
||||
implementation("io.swagger.codegen.v3:swagger-codegen-generators:1.0.50")
|
||||
|
||||
@ -35,6 +40,9 @@ dependencies {
|
||||
// https://mvnrepository.com/artifact/ch.qos.logback/logback-classic
|
||||
implementation("ch.qos.logback:logback-classic:1.5.6")
|
||||
|
||||
// https://mvnrepository.com/artifact/io.github.cdimascio/dotenv-kotlin
|
||||
implementation("io.github.cdimascio:dotenv-kotlin:6.4.1")
|
||||
|
||||
implementation(project(":common"))
|
||||
|
||||
testImplementation(kotlin("test"))
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user