【发布时间】:2021-06-21 01:03:50
【问题描述】:
我的目标是获取 GitHub Oauth 令牌以允许访问 GitHub 数据并提供对 Web 应用程序中其他 Ktor 路由的访问控制。 我将 Ktor 示例简化为仅使用 GitHub,并且工作正常并从 GitHub 获取令牌。 但是,从不调用身份验证块中的其他路由。例如,/github/repos 被识别为路由(没有 404),但会通过 GitHub 重新进行身份验证并显示“成功登录”页面,而不是“从 GitHib 获取并显示 repos 信息”。我确信我缺少一些基本的东西,但我很感激地得到了任何帮助。 谢谢,马丁
import io.ktor.application.*
import io.ktor.auth.*
import io.ktor.client.*
import io.ktor.client.engine.apache.*
import io.ktor.html.*
import io.ktor.locations.*
import io.ktor.routing.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import kotlinx.html.*
import java.util.concurrent.TimeUnit
val githubProvider = OAuthServerSettings.OAuth2ServerSettings(
name = "github",
authorizeUrl = "https://github.com/login/oauth/authorize",
accessTokenUrl = "https://github.com/login/oauth/access_token",
clientId = "**client-id**",
clientSecret = "**client-secret**",
defaultScopes = listOf("repo", "user")
)
@Location("/home") class home
@Location("/github/login") class gitHubLogin
@Location("/github/repos") class gitHubRepos
@Location("/github/user") class gitHubUser
@KtorExperimentalLocationsAPI
fun main(args: Array<String>) {
embeddedServer(Netty, port=8081) {
module()
}.start()
}
@KtorExperimentalLocationsAPI
fun Application.mainModule() {
install(Authentication) {
oauth("gitHubOAuth") {
client = HttpClient(Apache)
providerLookup = { githubProvider }
urlProvider = { url(gitHubLogin()) }
}
}
install(Locations)
install(Routing)
routing {
get<home> {
call.respondHtml {
head {
title { +"index page" }
}
body {
h1 {
+"Try to login"
}
p {
a(href = locations.href(gitHubLogin())) {
+"Login"
}
}
}
}
}
authenticate("gitHubOAuth") {
location<gitHubLogin>() {
param("error") {
handle {
call.loginFailedPage(call.parameters.getAll("error").orEmpty())
}
}
handle {
val principal = call.authentication.principal<OAuthAccessTokenResponse.OAuth2>()
if (principal != null) {
call.loggedInSuccessResponse(principal)
} else {
call.loginPage()
}
}
}
get<gitHubUser> {
call.respondHtml {
body {
p { +"Get and display user info from GitHib" }
}
}
}
get<gitHubRepos> {
call.respondHtml {
body {
p { +"Get and display repos info from GitHib" }
}
}
}
}
}
}
@KtorExperimentalLocationsAPI
private suspend fun ApplicationCall.loginPage() {
respondHtml {
head {
title { +"Login with" }
}
body {
h1 {
+"Login with:"
}
p {
a(href = application.locations.href(gitHubLogin())) {
+"GitHub"
}
}
}
}
}
private suspend fun ApplicationCall.loginFailedPage(errors: List<String>) {
respondHtml {
head {
title { +"Login with" }
}
body {
h1 {
+"Login error"
}
for (e in errors) {
p {
+e
}
}
}
}
}
@KtorExperimentalLocationsAPI
private suspend fun ApplicationCall.loggedInSuccessResponse(callback: OAuthAccessTokenResponse?) {
respondHtml {
head {
title { +"Logged in" }
}
body {
h1 {
+"You are logged in"
}
p {
+"Your token is $callback"
}
ul {
li {
a(href = locations.href(gitHubUser())) { +"User" }
}
li {
a(href = locations.href(gitHubRepos())) { +"Repos" }
}
}
}
}
}
【问题讨论】: