如何使用 NodeJS protect/store 对象服务器端?

How to protect/store an object server side with NodeJS?

我在 Web 应用程序中使用 AngularJS 和 NodeJS,用户必须在随机生成的问题之间找到正确答案。 我不知道如何"protect"客户的回答。

questions/answers 是在这样的对象中生成的:

var question = {
  answer: 'A',
  choices: ['A', 'B']
};

在此示例中,用户必须在 AB 之间进行选择,正确答案是 A.

我想做这样的事情:

  1. 客户端向服务器询问新问题
  2. 服务器仅将 question/answer 和 returns 选项 加载到客户端
  3. 客户端向服务器发送应答
  4. 服务器将客户端发送的答案与他的答案和returns发送给客户端的结果进行比较(即正确或错误)

由于questions/answers是随机生成的,所以答案需要在步骤1之后由服务器定义。

我在想类似的事情:

var answer = 0;

app.get('/generateQuestion', function (req, res) {
    var question = getQuestion();
    answer = question.answer
    res.send(question.choices);
});

app.post('/answer', function (req, res) {
    if (req.answer === answer) {
        res.send('Correct');
    } else {
        res.send('Wrong');
    }
});

但是这个存储的答案将在用户之间共享,从而导致冲突...

我想避免在提出问题时将答案发送给客户端,但我不知道如何在服务器端"store"它。

你会怎么处理?我怎样才能确保这个 questions/answers?

我无法添加评论,所以我必须 post 这作为答案,但我会使用类似 express-session 的东西将问题/答案存储在用户的会话中,它会自动存储您设置它的数据库中的数据。您可以通过将问题/答案对存储在数组中,然后将问题及其在数组中的索引发送给客户端来实现。然后他们可以发送答案和数组中的索引,您可以检查答案是否正确。

您可以考虑在浏览器端 JavaScript 对问题、可供选择的选项和正确答案进行编码,以防止随意查看。

请注意,这 不会 完全保护除了不熟练的用户之外的任何人的答案,但它会给你一些隐私。

这是我提出的解决方案(在 jsfiddle 上实时查看):

<div>Q:&nbsp;<span id="q"></span></div>
<div>1:&nbsp;<span id="o1"></span></div>
<div>2:&nbsp;<span id="o2"></span></div>
<div>3:&nbsp;<span id="o3"></span></div>
<div>Placeholder:&nbsp;<span id='p'></span></div>
<div>A:&nbsp;<span id='a'></span></div>

<script>
  var cc=''.charCodeAt,sh=[].shift,jo=[].join,sp=''.split,
      ma=[].map,fc=String.fromCharCode,lo=''.toLowerCase,
      fe=[].forEach,
      /* #1 */ r=function(s){
        var f=function(c){
          var v=cc.call(lo.call(c)),t=v>=96,k=(v-96+12)%26+1;
          if(v<97 || v>122) return c; return fc(k+(t?96:64));
        };
        return jo.call(ma.call(sp.call(s,''),f), '');
      },
      /* #2 */ d=[
        'Gur dhrfgvba gb nfx?',   // The question to ask?
        'Svefg cbffvoyr nafjre',  // First possible answer
        'Frpbaq cbffvoyr nafjre', // Second possible answer
        'Guveq cbffvoyr nafjre',  // Third possible answer
        '[Naq gur nafjre vf...]', // [And the answer is...]
        'Gur npghny nafjre!',     // The actual answer!
      ],
      /* #3 */ t=['q','o1','o2','o3','p','a'];

  /* #4 */ fe.call(t,function(tr){
    document.getElementById(tr).innerText=r(sh.call(d));
  });
</script>

在哪里

  • #1:rROT13 variation of the Caesar Cypher
  • 的混淆实现
  • #2:d 是一个 ROT13 编码字符串数组,每次向用户呈现新问题时都应替换它
  • #3:t 是一个包含 DOM 个元素 ID 的数组,用于标识要将解码后的字符串插入到哪些元素中
  • #4:将解码后的字符串插入到相应的元素中。

当从服务器检索到每个新问题时,问题的编码值、答案的选择、答案的占位符以及实际答案本身都会替换 d 中的值。

在您的应用程序中,选项可能是带有附加 onClick 事件处理程序的单选按钮,这些事件处理程序将根据解码的答案检查单击的选项以确定成功或失败。

这是 ROT13 密码的未混淆版本:

var rot13 = function(s){
    return s.split('').map(function(c){
      var v=c.toLowerCase().charCodeAt(0);
      if(v<97 || v>122) return c;
      var t = v>=96,
          k = (v - 96 + 12) % 26 + 1;
      return String.fromCharCode(k + (t ? 96 : 64));
  }).join('');
};