谷歌recaptcha nodejs应用程序

时间:2017-12-10 23:14:59

标签: node.js recaptcha

好的,我正在尝试将Google Recaptcha应用到我的应用的注册页面中。前端的所有内容似乎都可以加载页面,当我点击“我不是机器人”时,它会要求我验证图像然后......当我点击提交时,它会告诉我“请选择验证码” “它将我重定向回注册页面。多数民众赞成如何设置代码,如果有人没有选择验证码复选标记,但我无法弄清楚为什么它不会继续并创建用户。这是代码......

// handle signup logic
router.post("/register", function(req, res) {
  if(req.body.captcha === undefined || req.body.captcha === "" || req.body.captcha === null){
      req.flash("error", "Please select captcha");
      return res.redirect("/register");
    }
    // secret key
    var secretKey = process.env.CAPTCHA;
    // Verify URL
    var verifyURL = `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${req.body.captcha}&remoteip=${req.connection.remoteAddress}`;
    // Make request to Verify URL
    request(verifyURL, (err, response, body) => {
      // if not successful
      if(body.success !== undefined && !body.success){
        req.flash("error", "Captcha Failed");
        return res.redirect("/register");
      }

      // if successful
      upload(req, res, function(err) {
        if(err){
          console.log(err.message);
          req.flash("error", err.message);
          return res.redirect("/register");
       }
       var newUser = new User({
         username: req.body.username,
         firstName: req.body.firstName,
         lastName: req.body.lastName,
         email: req.body.email,
         bio: req.body.bio
       });

       if(typeof req.file !== "undefined") {
         newUser.avatar = '/uploads/userImg/' + req.file.filename;
       } else {
         newUser.avatar = '/uploads/userImg/no-image.png';
       }
       console.log(newUser);
       if(req.body.adminCode === process.env.ADMINCODE) {
         newUser.isAdmin = true;
      }

      if(req.body.answer !== process.env.SECRET){
        req.flash("error", "answer the question");
        return res.redirect("back");
      } else {
        User.register(newUser, req.body.password, function(err, user){
          if(err){
            console.log(err.message);
            return res.render("register", {error: err.message});
          }
          passport.authenticate("local")(req, res, function(){
            req.flash("success", "Welcome to Let's Camp " + user.username);
            res.redirect("/campgrounds"); 
          }); 
        });
      }
    });
  });

 });

<% include ./partials/header %>

<div class="row">
    <div class="col-md-8 col-md-offset-2">
      <form id="register" action="/register" method="post" enctype="multipart/form-data">
        <h1 class="text-center">Sign Up</h1>
    </div>
    <div class="row">
      <div class="col-md-4 col-md-offset-2 col-xs-8 col-xs-offset-2">
        <div class="form-group">
          <label for="firstName">First Name</label>
          <input id="firstName" class="form-control" type="text" id="firstName" name="firstName" placeholder="First Name*" required>
        </div>
      </div>
      <div class="col-md-4 col-md-offset-0 col-xs-8 col-xs-offset-2">
        <div class="form-group">
          <label for="lastName">Last Name</label>
          <input id="lastName" class="form-control" type="text" id="lastName" name="lastName" placeholder="Last Name*" required>
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col-md-4 col-md-offset-2 col-xs-8 col-xs-offset-2">
        <div class="form-group">
          <label for="email">Email</label>
          <input id="email" class="form-control" type="email" id="email" name="email" placeholder="Email*" required>
        </div>
      </div>
      <div class="col-md-4 col-md-offset-0 col-xs-8 col-xs-offset-2">
        <div class="form-group">
          <label for="avatar">Avatar Image URL</label>
          <input id="avatar" class="form-control" type="file" name="avatar">
        </div>
      </div>
    </div>
    <div class="row">
     <div class="col-md-4 col-md-offset-2 col-xs-8 col-xs-offset-2">
        <div class="form-group">
          <label for="username">Username</label>
          <input id="username" class="form-control" type="text" id="username" name="username" placeholder="Username*" required>
        </div>
      </div>
      <div class="col-md-4 col-md-offset-0 col-xs-8 col-xs-offset-2">
        <div class="form-group">
          <label for="password">Password</label>
          <input id="password" class="form-control" type="password" id="password" name="password" placeholder="Password*" required>
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col-md-8 col-md-offset-2 col-xs-8 col-xs-offset-2">
        <div class="form-group">
          <label for="bio">Bio</label>
          <textarea id="bio" class="form-control" type="bio" name="bio" rows="5" placeholder="Write a short description of yourself and what you enjoy about camping."></textarea>
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col-md-4 col-md-offset-2 col-xs-8 col-xs-offset-2">
        <div class="form-group">
          <label for="adminCode">Admin Code</label>
          <input id="adminCode" class="form-control" type="text" name="adminCode" placeholder="Admin Code">
        </div>
      </div>
      <div class="col-md-4 col-md-offset-0 col-xs-8 col-xs-offset-2">
        <div class="form-group">
          <label for="number">Enter: Answer</label>
          <input id="number" class="form-control" type="text" id="answer" name="answer" placeholder="Answer*" required>
        </div>
      </div>
    </div>
    <div class="row">
      <div class="col-md-4 col-md-offset-4">
        <div class="g-recaptcha form-group" data-sitekey="6LduxzsUAAAAAAoten8FA_zg12PjA3QfSjF5vFvY"></div>
      </div>
    </div>
    <div class="row">
      <div class="col-md-8 col-md-offset-2 col-xs-8 col-xs-offset-2">
        <div class="form-group">
          <button class="btn btn-lg btn-primary btn-block">Sign Up!</button>
        </div>
        <a href="/campgrounds">Go Back</a>
        </form>
      </div>
    </div>
    <div class="row">
        <div class="col-md-12 col-xs-8 col-xs-offset-2">
            <p class="text-center"><strong>*</strong> indicates a required field.</p>
        </div>
    </div>
  </div>

<% include ./partials/footer %>

1 个答案:

答案 0 :(得分:1)

不是req.body.captcha

好像你没有正确阅读教程。

来自this tutorial就是这样的例子:

app.post('/submit',function(req,res){
  // g-recaptcha-response is the key that browser will generate upon form submit.
  // if its blank or null means user has not selected the captcha, so return the error.
  if(req.body['g-recaptcha-response'] === undefined || req.body['g-recaptcha-response'] === '' || req.body['g-recaptcha-response'] === null) {
    // not passed validation
  }

this file开始,会在第52行看到此类代码:

if(req.body && req.body['g-recaptcha-response']) response = req.body['g-recaptcha-response'];

他们都证明可以在req.body['g-recaptcha-response']

下访问“隐形”字段


这里是固定的:

这个:

const captcha = req.body['g-recaptcha-response'];
if(!captcha){
  req.flash("error", "Please select captcha");
  return res.redirect("/register");
}

和此:

// Verify URL
var verifyURL = `https://www.google.com/recaptcha/api/siteverify?secret=${secretKey}&response=${captcha}&remoteip=${req.connection.remoteAddress}`;

或者只创建简单的中间件catchReCaptcha并附加到路由器:

// middleware that catches g-recaptcha-response and puts in req.body.captcha
const catchReCaptcha = (req, res, next) => {
  if(req.body && req.body['g-recaptcha-response']) {
    req.body.captcha = req.body['g-recaptcha-response'];
  }
  next();
};

// attached middleware to register route
router.post("/register", catchReCaptcha, (req, res) => { 

但请记住,由于multipart/form-data方法负责解析该内容类型的请求主体,因此您将解析upload的冲突。