如何使用NodeJS保护/存储对象服务器端?

时间:2016-03-21 15:41:46

标签: node.js client-server

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

问题/答案在以下对象中生成:

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

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

我想做那样的事情:

  1. 客户要求服务器提出新问题
  2. 服务器加载问题/答案并仅将选项返回给客户
  3. 客户端向服务器发送答案
  4. 服务器将客户端发送的答案与答案进行比较,并将结果返回给客户端(即正确或错误)
  5. 由于问题/答案是随机生成的,因此需要在步骤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');
        }
    });
    

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

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

    你会怎么处理?我怎样才能确定这个问题/答案?

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

您可以考虑对浏览器端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:r是对ROT13
  • 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('');
};