2017-09-30 62 views
1

我是012,和Ktor嘗試查看身份驗證部分的新手,所以我獲得了下面的代碼。在Ktor中的表單身份驗證

路由「/」和「/再見」工作正常,但路由「登錄」給出的空白頁!

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

你不是簡單地給出一個空白頁面,你會得到一個HTTP狀態代碼401 (UNAUTHORIZED)。這是因爲formAuthentication有四個參數,其中三個參數具有默認值。您只執行最後一個(validate,沒有默認值):

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

每當你不已經到位正確的憑證到達/login路線,你會得到challenge默認,這是FormAuthChallenge.Unauthorized,這是一個401響應。

而不是使用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-parameterpassword-parameter清楚,因爲他們出現在form是做POST,如如下:

 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」,..'非常感謝。 –