【问题标题】:google recaptcha nodejs app谷歌recaptcha nodejs应用程序
【发布时间】:2018-05-24 11:28:12
【问题描述】:

好的,我正在尝试将 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 %>

【问题讨论】:

  • 添加html来回答。
  • @num8er,我把它加到了底部。谢谢
  • 我的 header.ejs 文件中有
  • 在你的html中我没有captcha字段,所以它是由google的js代码生成的。通过许多教程,我看到验证码数据存储在:req.body['g-recaptcha-response']
  • 那么我应该在哪里添加验证码字段?或使用 req.body['g-recaptcha-response' ?我只是在问,因为我是基于一些教程加上我在谷歌网站上看到的,这是我所知道的

标签: node.js recaptcha


【解决方案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) => { 

但请记住,由于 upload 方法也负责解析该内容类型的请求正文,因此您将在解析 multipart/form-data 时遇到冲突。

【讨论】:

  • 即使有这个修复,它仍然告诉我选择验证码并重新开始表单......
  • 您使用过哪个修复示例?
  • @DarrellPawson 你可以在router.post 行下做console.log(req.body) 并尝试再次传递它,然后复制控制台的输出该日志在哪里并将其放在 cmets 中?
  • {} 这就是我的全部
  • 你发的前两个...中间件我还没做
猜你喜欢
  • 1970-01-01
  • 2021-06-17
  • 2022-06-16
  • 2015-12-24
  • 1970-01-01
  • 2018-03-19
  • 2015-02-25
  • 2017-05-19
  • 1970-01-01
相关资源
最近更新 更多