我可以使用RE-Captcha和Wicket吗?

时间:2012-03-28 13:29:23

标签: apache recaptcha wicket-1.5

我可以使用apache wicket 1.5.3的recaptcha吗?有一些很好的例子吗?

3 个答案:

答案 0 :(得分:1)

就Google reCAPTCHA v2而言,您可以按照其说明进行操作,这很简单。

首先,转到Google reCAPTCHA,然后在那里注册您的应用程序。然后,您可以分别在客户端和服务器端工作,如下所示:

在客户端(see ref

首先,将代码段粘贴到HTML模板上结束标记之前的<script...></script>下方,例如:

    <script src='https://www.google.com/recaptcha/api.js'></script>
</head>

然后将<div...></div>下方的代码段粘贴到您希望显示reCAPTCHA小部件的位置的末尾,例如:

    <div class="g-recaptcha" data-sitekey="{your public site key given by Google reCAPTCHA}"></div>
</form>

这一切都在客户端。

在服务器端(see ref

当用户提交表单时,您需要从g-recaptcha-response POST参数获取用户响应令牌。然后使用令牌以及Google reCAPTCHA提供的密钥,以及用户的IP地址可选,然后将请求发送到Google reCAPTCHA API。然后,您将收到Google reCAPTHA的回复,表明表单验证是成功还是失败。

以下是服务器端的示例代码。

  • 用户提交Wicket表格(本例中为Wicket 6):
protected void onSubmit() {
    HttpServletRequest httpServletRequest = (HttpServletRequest)getRequest().getContainerRequest();
    boolean isValidRecaptcha = ReCaptchaV2.getInstance().verify(httpServletRequest);
    if(!isValidRecaptcha){
        verificationFailedFeedbackPanel.setVisible(true);
        return;
    }

    // reCAPTCHA verification succeeded, carry on handling form submission
    ...
}

ReCaptchaV2.java(Just Java,独立于Web框架)

import javax.servlet.http.HttpServletRequest;    
import org.apache.log4j.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;


public class ReCaptchaV2 {

    private final static Logger logger = Logger.getLogger(ReCaptchaV2.class);

    private final static String VERIFICATION_URL = "https://www.google.com/recaptcha/api/siteverify";
    private final static String SECRET = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

    private static ReCaptchaV2 instance = new ReCaptchaV2();

    private ReCaptchaV2() {}

    public static ReCaptchaV2 getInstance() {
        return instance;
    }

    private boolean verify(String recaptchaUserResponse, String remoteip) {
        boolean ret = false;
        if (recaptchaUserResponse == null) {
            return ret;
        }

        RestTemplate rt = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        MultiValueMap<String, String> map= new LinkedMultiValueMap<String, String>();
        map.add("secret", SECRET);
        map.add("response", recaptchaUserResponse);
        if (remoteip != null) {
            map.add("remoteip", remoteip);
        }
        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<MultiValueMap<String, String>>(map, headers);

        ResponseEntity<String> res = null;
        try {
            res = rt.exchange(VERIFICATION_URL, HttpMethod.POST, httpEntity, String.class);
        } catch (Exception e) {
            logger.error("Exception: " + e.getMessage());
        }

        if (res == null || res.getBody() == null) {
            return ret;
        }

        Response response = null;
        try {
            response = new ObjectMapper().readValue(res.getBody(), Response.class);
        } catch (Exception e) {
            logger.error("Exception: " + e.getMessage());
        }

        if (response != null && response.isSuccess()) {
            ret = true;
        }

        logger.info("Verification result: " + ret);
        return ret;
    }

    public boolean verify(HttpServletRequest httpServletRequest) {
        boolean ret = false;
        if (httpServletRequest == null) {
            return ret;
        }

        String recaptchaUserResponse = httpServletRequest.getParameter("g-recaptcha-response");
        String remoteAddr = httpServletRequest.getRemoteAddr();
        return verify(recaptchaUserResponse, remoteAddr);
    }
}

Response.java(Java POJO)

public class Response {
    private String challenge_ts;
    private String hostname;
    private boolean success;

    public Response() {}

    public String getChallenge_ts() {
        return challenge_ts;
    }

    public void setChallenge_ts(String challenge_ts) {
        this.challenge_ts = challenge_ts;
    }

    public String getHostname() {
        return hostname;
    }

    public void setHostname(String hostname) {
        this.hostname = hostname;
    }

    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    @Override
    public String toString() {
        return "ClassPojo [challenge_ts = " + challenge_ts + ", hostname = " + hostname + ", success = " + success + "]";
    }
}

答案 1 :(得分:0)

您是否阅读过this

我已在此处添加了指南,以防页面消失。

<强>用法

我们将创建一个名为RecaptchaPanel的面板。为了将此组件用于您的应用程序,您只需要这样做:

add(new RecaptchaPanel("recaptcha"));

当然,在标记中添加组件:

<div wicket:id="recaptcha"></div>

<强>实施

实施很简单。您所要做的就是遵循以下几个步骤:

将recaptcha依赖项添加到项目中

<dependency>
 <groupid>net.tanesha.recaptcha4j</groupid>
 <artifactid>recaptcha4j</artifactid>
 <version>0.0.7</version>
</dependency>

该库隐藏了实现细节,并公开了用于处理recaptcha服务的API。

创建关联标记(RecaptchaPanel.html)

<wicket:panel><div wicket:id="captcha"></div></wicket:panel>

创建RecaptchaPanel.java

import net.tanesha.recaptcha.ReCaptcha;
import net.tanesha.recaptcha.ReCaptchaFactory;
import net.tanesha.recaptcha.ReCaptchaImpl;
import net.tanesha.recaptcha.ReCaptchaResponse;

/**
 * Displays recaptcha widget. It is configured using a pair of public/private keys which can be registered at the
 * following location:
 * 
* https://www.google.com/recaptcha/admin/create
 * <br>
 * More details about recaptcha API: http://code.google.com/apis/recaptcha/intro.html
 *
 * @author Alex Objelean
 */
@SuppressWarnings("serial")
public class RecaptchaPanel extends Panel {
  private static final Logger LOG = LoggerFactory.getLogger(RecaptchaPanel.class);
  @SpringBean
  private ServiceProvider serviceProvider;


  public RecaptchaPanel(final String id) {
    super(id);
    final ReCaptcha recaptcha = ReCaptchaFactory.newReCaptcha(serviceProvider.getSettings().getRecaptchaPublicKey(),
      serviceProvider.getSettings().getRecaptchaPrivateKey(), false);
    add(new FormComponent<void>("captcha") {
      @Override
      protected void onComponentTagBody(final MarkupStream markupStream, final ComponentTag openTag) {
        replaceComponentTagBody(markupStream, openTag, recaptcha.createRecaptchaHtml(null, null));
      }

      @Override
      public void validate() {
        final WebRequest request = (WebRequest)RequestCycle.get().getRequest();

        final String remoteAddr = request.getHttpServletRequest().getRemoteAddr();
        final ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
        reCaptcha.setPrivateKey(serviceProvider.getSettings().getRecaptchaPrivateKey());

        final String challenge = request.getParameter("recaptcha_challenge_field");
        final String uresponse = request.getParameter("recaptcha_response_field");
        final ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(remoteAddr, challenge, uresponse);

        if (!reCaptchaResponse.isValid()) {
          LOG.debug("wrong captcha");
          error("Invalid captcha!");
        }
      }
    });
  }
}
</void>

需要注意的事项:

  • ServiceProvider - 是一个包含reCaptcha配置(公钥和私钥)的spring bean。这些密钥根据部署应用程序的域而不同(默认情况下,在使用localhost域时适用于任何密钥)。您可以在此处生成密钥:https://www.google.com/recaptcha/admin/create
  • RecaptchaPanel包含一个FormComponent,它允许实现包含验证逻辑的validate方法。
  • 由于reCaptcha对隐藏字段使用硬编码值,因此该组件在同一页面上不能有多个独立实例。

答案 2 :(得分:0)

也许xaloon wicket组件可以为您提供解决方案。他们有一个Recaptcha插件。