Sto tentando di autenticare gli utenti tramite il servizio di autenticazione remota. Ho scritto metodo di supporto per l'invio di un messaggio di servizio e di attesa per il risultato:Limitazione modulo riproduzione 1
def authenticateAwait(email: String,
password: String
): Either[String, Option[User]] = {
try {
val future = authenticate(email, password)
Right(Await.result(future, timeout.duration))
} catch {
case _ ⇒ Left("Unable to connect to authentication server")
}
}
Riporta Left[String]
con una descrizione errore se il messaggio non può essere inviato, o non c'è risposta. Se la risposta del servizio ricevuto, restituisce Right[Option[User]]
. Il servizio risponde con Option[User]
in base al risultato dell'autenticazione.
per eseguire l'autenticazione effettiva Ho creato forma con un paio di validatori, eccolo:
val loginForm = Form(
tuple(
"email" → email,
"password" → nonEmptyText
) verifying ("Invalid email or password", result => result match {
case (email, password) ⇒
User.authenticateAwait(email, password) match {
case Left(_) ⇒ true
case Right(optUser) ⇒ optUser.isDefined
}
}) verifying ("Unable to connect to authentication server", result => result match {
case (email, password) ⇒
User.authenticateAwait(email, password) match {
case Left(_) ⇒ false
case Right(optUser) ⇒ true
}
})
)
Una cosa mi preoccupa di questo codice, si chiama authenticateAwait
due volte. Significa che verranno inviati esattamente due messaggi per singola convalida. Quello di cui ho effettivamente bisogno, è di chiamare authenticateAwait
una volta, memorizzare i risultati ed eseguire varie convalide su di esso. Sembra che non ci sia una soluzione semplice.
Per eseguire l'autenticazione, accedere ai campi modulo richiesti, significa che il modulo deve essere associato e quindi convalidato, ma non c'è modo di allegare errori al modulo esistente (sbaglio?).
Gli errori possono essere allegati al modulo solo durante la sua creazione, pertanto dovrei eseguire l'autenticazione nei validatori, ma il problema sopracitato si verifica.
La soluzione temporanea con cui sono arrivato è definire un metodo e un var
al suo interno.
def loginForm = {
var authResponse: Either[String, Option[commons.User]] = null
Form(
tuple(
"email" → email,
"password" → nonEmptyText
) verifying ("Invalid email or password", result ⇒ result match {
case (email, password) ⇒
authResponse = User.authenticateAwait(email, password)
authResponse match {
case Left(_) ⇒ true
case Right(optUser) ⇒ optUser.isDefined
}
}) verifying ("Unable to connect to authentication server", result ⇒ result match {
case (email, password) ⇒
authResponse match {
case Left(_) ⇒ false
case Right(optUser) ⇒ true
}
})
)
}
Questo è chiaramente un hack. Ci sono soluzioni migliori?
Aggiornamento: A mio parere, la forma dovrebbe sterilizzare solo ingresso, ma l'autenticazione deve essere eseguita in seguito al di fuori del modulo. Il problema è che gli errori vengono inviati alla vista come parte di Form
ed è impossibile allegare errori al modulo esistente. Non esiste un modo semplice per creare un nuovo modulo con gli errori.
si chiama AJAX; usalo e non creerai blocchi di codice ginormi cercando di risolvere un problema che non esiste (suggerimento: non è necessario creare un nuovo modulo) – virtualeyes