2017-09-30 4 views
1

인증 부분을 보려고 시도한 KotlinKtor을 처음 사용하므로 아래 코드를 얻었습니다.Ktor의 폼 인증

경로 "/"와 "/ bye"는 정상적으로 작동하지만 경로가 "빈 페이지"인 경우!

package blog 

import kotlinx.html.* 
import kotlinx.html.stream.* // for createHTML 
import org.jetbrains.ktor.application.* 
import org.jetbrains.ktor.auth.* 
import org.jetbrains.ktor.features.* 
import org.jetbrains.ktor.http.* 
import org.jetbrains.ktor.response.* 
import org.jetbrains.ktor.routing.* 

import org.jetbrains.ktor.request.* // for request.uri 

import org.jetbrains.ktor.html.* 
import org.jetbrains.ktor.pipeline.* 

import org.jetbrains.ktor.host.* // for embededServer 
import org.jetbrains.ktor.netty.* // for Netty 

fun main(args: Array<String>) { 
    embeddedServer(Netty, 8080, watchPaths = listOf("BlogAppKt"), module = Application::module).start() 
} 

fun Application.module() { 
    install(DefaultHeaders) 
    install(CallLogging) 

    intercept(ApplicationCallPipeline.Call) { 
     if (call.request.uri == "/hi") 
      call.respondText("Test String") 
    } 

    install(Routing) { 
     get("/") { 
      call.respondText("""Hello, world!<br><a href="/bye">Say bye?</a>""", ContentType.Text.Html) 
     } 
     get("/bye") { 
      call.respondText("""Good bye! <br><a href="/login">Login?</a> """, ContentType.Text.Html) 
     } 
     route("/login") { 
      authentication { 
       formAuthentication { up: UserPasswordCredential -> 
        when { 
         up.password == "ppp" -> UserIdPrincipal(up.name) 
         else -> null 
        } 
       } 
      } 

      handle { 
       val principal = call.authentication.principal<UserIdPrincipal>() 
       if (principal != null) { 
        call.respondText("Hello, ${principal.name}") 
       } else { 
         val html = createHTML().html { 
         body { 
          form(action = "/login", encType = FormEncType.applicationXWwwFormUrlEncoded, method = FormMethod.post) { 
           p { 
            +"user:" 
            textInput(name = "user") { 
             value = principal?.name ?: "" 
            } 
           } 

           p { 
            +"password:" 
            passwordInput(name = "pass") 
           } 

           p { 
            submitInput() { value = "Login" } 
           } 
          } 
         } 
        } 
        call.respondText(html, ContentType.Text.Html) 
       } 
      } 
     } 
    } 
} 

내가 인증 부분 아래에 사용할 경우, 경로 '/ 로그인'오류가이 부분에서 또는 전화의 방법으로 가능성이 높습니다 의미 필요한 양식을 표시? 그렇 겠지.

  authentication { 
       formAuthentication { up: UserPasswordCredential -> 
        when { 
         up.password == "ppp" -> UserIdPrincipal(up.name) 
         else -> null 
        } 
       } 
      } 

답변

0

단순히 빈 페이지가 아니라, 401 (UNAUTHORIZED)의 HTTP 상태 코드가 표시됩니다. formAuthentication에는 4 개의 매개 변수가 있으며 그 중 3 개는 기본값이 있기 때문입니다. 당신은 (디폴트없이, validate) 마지막 하나를 구현 : 이미 장소에 적절한 자격 증명없이 /login 경로에 도달 할 때마다

userParamName: String = "user", 
passwordParamName: String = "password", 
challenge: FormAuthChallenge = FormAuthChallenge.Unauthorized, 
validate: (UserPasswordCredential) -> Principal? 

, 당신은 401 응답이 FormAuthChallenge.Unauthorized입니다 challenge의 기본을 얻을 .

challenge의 기본값을 사용하는 대신 FormAuthChallenge.Redirect을 사용할 수 있습니다. 이 개 루트 필요로하는 간단한 예제 : 위가 잘 작동하지 않은 경우

get("/login") { 
    val html = """ 
      <form action="/authenticate" enctype="..." 
      REST OF YOUR LOGIN FORM 
      </form> 
      """ 
    call.respondText(html, ContentType.Text.Html) 
} 

route("/authenticate") { 
    authentication { 
     formAuthentication(challenge = FormAuthChallenge.Redirect({ _, _ -> "/login" })) { 
      credential: UserPasswordCredential -> 
      when { 
       credential.password == "secret" -> UserIdPrincipal(credential.name) 
       else -> null 
      } 
     } 
    } 

    handle { 
     val principal = call.authentication.principal<UserIdPrincipal>() 
     val html = "Hello, ${principal?.name}" 
     call.respondText(html, ContentType.Text.Html) 
    } 
} 

UPDATE

정의, 모두 userid-parameter 그들이 같이 POST을 그 form에 나타나는대로 명확하게 password-parameter 아래 :

 authentication { 
      formAuthentication("user", "pass", 
        challenge = FormAuthChallenge.Redirect({ _, _ -> "/login" })){ 
       credential: UserPasswordCredential -> 
       when { 
       credential.password == "secret" -> UserIdPrincipal(credential.name) 
       else -> null 
       } 
      } 
     } 
+0

그것은 상태 302''주어진 관계없이 암호를 입력 한'\의 login' 페이지 :( –

+0

그것은 괜찮 았는데를 다시로드 계속된다 내가'formAuthentication ("user", "pass", ..'thanks 많이 사용했습니다. –