I have the task of maintaining a small application written with PlayFramework 1.2.x. One item that needs done: adding a Captcha to the login page. This is apparently harder than one thinks, since the login-page is handled semi-automatically by the Secure module.
When handling a normal HTTP form, the PlayFramework passes the form variables to the controller method as parameters. Using the standard Secure module, the login form contains only the user-name and the password, and these are passed to the authenticate method.
Now, I can create a custom login-form that includes a captcha, and I am also allowed to override the authenticate method in the Secure module. The problem is this: I cannot change the parameters of the authenticate method to include the captcha-code, or else it is no longer overriding the method in the superclass (and the method is then never called).
Here is a simple login form, with the Captcha adapted from the “yabe” example:
#{extends 'main.html' /} #{set title:'Login' /}
#{form @authenticate()}
<p>
<label for="username">User name: </label> <input type="text"
name="username" id="username" maxlength="30"
value="${params.username}" />
</p>
<p>
<label for="password">Password: </label> <input type="password"
name="password" id="password" maxlength="30" " />
</p>
<p>
<label for="code">Please type the code below: </label> <img
src="@{Captcha.captcha(randomID)}" /> <br /> <input type="text"
name="code" id="code" size="18" value="" /> <input type="hidden"
name="randomID" value="${randomID}" />
</p>
<p>
<input type="submit" id="signin" value="Log in" />
</p>
#{/form}
Here is a simple authenticate method that does not work, because “code” and “randomID” are undefined. Again, I cannot just add the parameters to authenticate, or else it no longer overrides the method from the superclass, and is not called.
package controllers;
import play.cache.Cache;
import play.data.validation.Required;
import models.*;
public class Security extends Secure.Security {
static boolean authenticate(String username, String password) {
boolean auth = false;
if (code.equals(Cache.get(randomID))) {
auth = (User.connect(username, password) != null);
}
return auth;
}
}
Question: how can I get the values “code” and “randomID” from the form to the authenticate method? Is there some other way of accessing values from the form?
You are in a Play! controller, so you have access to the object
request.params, out of which you can fetch the parameters, as inrequest.params.get("code").