Настройка моей первой ExpressJS страницы портфолио с логинами пользователей с использованием Passport JS. Я хотел добавить ReCAPTCHA V2 от Google в процесс входа в систему, но я получаю сообщение об ошибке при объединении Passport и ReCAPTCHA.
Ошибка: SyntaxError: JSON .parse: неожиданный символ в строке 1 столбец 1 JSON данных
Я считаю, что ошибка связана с тем, как я настроил return next () в моем разделе POST, но я не могу понять, почему. Я пробовал несколько разных конфигураций, и поиск в Google не дал результатов.
Если я удаляю код паспорта JS в разделе POST, код ReCAPTCHA V2 работает. Я, конечно, упускаю что-то простое, но теряюсь, как заставить их работать вместе. Любая помощь приветствуется.
ПРИМЕЧАНИЕ: Я удалил два ключа ReCAPTCHA V2 для обеспечения безопасности (ключ сайта и секретный ключ), их нужно будет заменить на рабочие ключи от Google ReCAPTCHA версия 2 .
const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const passport = require('passport');
const mongoose = require('mongoose');
const LocalStrategy = require('passport-local').Strategy;
const app = express();
mongoose.connect('mongodb://localhost/MyDatabase', { useNewUrlParser: true, useUnifiedTopology: true });
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(
function (username, password, done) {
UserDetails.findOne({
username: username
}, function (err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false);
}
if (user.password != password) {
return done(null, false);
}
return done(null, user);
});
}
));
passport.serializeUser(function (user, cb) {
cb(null, user.id);
});
passport.deserializeUser(function (id, cb) {
User.findById(id, function (err, user) {
cb(err, user);
});
});
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
const Schema = mongoose.Schema;
const UserDetail = new Schema({
username: String,
password: String
});
const UserDetails = mongoose.model('userInfo', UserDetail, 'userInfo');
app.post('/', (req, res) => {
if (
req.body.captcha === undefined ||
req.body.captcha === '' ||
req.body.captcha === null
) {
return res.json({ "success": false, "msg": "Please select captcha" }); // If no CAPTCHA is selected / checkbox not checked
}
// secret key
const secretKey = 'INSERT SECRET KEY'; // You need to add a secret key from Google ReCAPTCHA V2
// verify URL
const verifyUrl = `https://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) => {
body = JSON.parse(body);
console.log("parsed body: ", body);
// if not successful
if (body.success !== undefined && !body.success) {
console.log("Request verifyUrl failed");
return res.json({ "success": false, "msg": "Failed captcha vericiation" }); // if can't connect to Google and verify CAPTCHA
}
// line below works if passport code and next() is removed
// return res.json({ "success": true, "msg": "captcha passed!" }); // Connected to Google and verified CAPTCHA
});
return next(); // Is the error coming from this?
},
passport.authenticate('local'),
function (req, res) {
console.log("Passport function was called ...");
// If this function gets called, authentication was successful.
// `req.user` contains the authenticated user.
res.redirect('/success');
});
// ####################### PASSPORT
// ######################### PASSPORT END
app.listen(3000, () => {
console.log("SERVER STARTED on port 3000")
});
my HTML file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script src="//www.google.com/recaptcha/api.js"></script>
<title>Recaptcha and Passport Test</title>
</head>
<body>
<div class="container">
<h1>Subscribe</h1>
<form id="subscribeForm">
<div class="form-group">
<label for="username">Username</label>
<input type="text" name="username" class="form-control" id="username">
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" name="password" class="form-control" id="password">
</div>
<div class="form-group">
<div class="g-recaptcha" data-sitekey="SITE KEY GOES HERE"></div>
</div>
<input type="submit" value="submit" class="btn btn-primary">
</form>
</div>
<script>
document.getElementById('subscribeForm').addEventListener('submit', submitForm);
function submitForm(e) {
e.preventDefault();
const username = document.querySelector('#username').value;
const password = document.querySelector('#password').value;
const captcha = document.querySelector('#g-recaptcha-response').value;
fetch('/', {
method: 'POST',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-type': 'application/json'
},
body: JSON.stringify({username: username, password: password, captcha: captcha})
})
.then((res) => res.json())
.then((data) => {
console.log("Fetch data: ", data);
})
}
</script>
</body>
</html>
Чтобы увидеть, что он работает без ошибок, удалите код passport.authenticate в разделе POST и возврат next () над ним. Также раскомментируйте возвращаемую рез. json строку успеха над следующей ().