簡體   English   中英

req.session.captcha 不適用於 Node.js 中的不同端口

[英]req.session.captcha is not working on different port in Node.js

我試圖通過存儲到req.session對象來驗證驗證碼。

快速服務器在 8181 上運行,客戶端在 3000 上運行。但在驗證驗證碼中req.session.captcha是未定義的。 請幫我。

我的服務器代碼:

var captchapng = require('captchapng');
var express = require('express');
var app = express();
var session = require('express-session');
var cookieParser = require('cookie-parser');

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
  });

app.use(cookieParser());
app.use(session({
    secret: 'abcd',
    resave: false,
    saveUninitialized: false,
    cookie: {maxAge: 1000*60*60*24*30}, //30 days
  }));



app.get('/captcha.png', function (request, response) {
    if(request.url == '/captcha.png') {
        var randNumber = Math.random()*9000+1000;
        var p = new captchapng(80,30,parseInt(randNumber)); // width,height,numeric captcha
        p.color(0, 0, 0, 0);  // First color: background (red, green, blue, alpha)
        p.color(80, 80, 80, 255); // Second color: paint (red, green, blue, alpha)
        var no  = parseInt(randNumber);
        request.session.captcha = no.toString();
        console.log(parseInt(randNumber));
        console.log(request.session);
        var img = p.getBase64();
        var imgbase64 = new Buffer(img,'base64');
        response.writeHead(200, {
            'Content-Type': 'image/png'
        });
        response.end(imgbase64);
    } else response.end('');
})

app.get('/verify-captcha', (req, res) => {
    let captcha = req.query.captcha;
    console.log(captcha, req.session);
    if(req.session.captcha === Number(captcha)){
        res.send({message:'verified'})
    }
    else
        res.send({message: "Not Verified!"})
})

app.listen(8181);

我的客戶代碼:

索引.pug

extends layout

block content
  h1= title
  p Welcome to #{title}
  #image
    img(src="http://localhost:8181/captcha.png")
  #verify
    input(type="text" placeholder="Enter captcha to verify" id="captcha")
    button(type="button") Submit

驗證碼

$(document).ready(function(){
    $('button').click(function(e){
        var captcha = $('#captcha').val();
        alert(captcha)
        $.ajax({
            url: 'http://localhost:8181/verify-captcha?captcha='+captcha,
            type:'GET',
            success: function(data){
                alert(data)
            },
            error: function(err) {
                alert(err);
            }
        })
    })
})

看起來像app.use(cookieParser()); 問題是...

來自快速會話文檔:

從版本 1.5.0 開始,不再需要使用 cookie-parser 中間件來使該模塊工作。 該模塊現在直接在 req/res 上讀取和寫入 cookie。 如果此模塊和 cookie-parser 之間的秘密不相同,則使用 cookie-parser 可能會導致問題。

刪除cookieParser或使用相同的秘密app.use(cookieParser('abcd')); .

還:

您的客戶端代碼有一個錯字:

url: 'http://localhost:8181/verify-captch?captcha='+captcha,

應該

url: 'http://localhost:8181/verify-captcha?captcha='+captcha,

在您的服務器代碼中,您將 String 與 Number 進行比較,應該是這樣的:

app.get('/verify-captcha', (req, res) => {
    let captcha = req.query.captcha;
    console.log(captcha, req.session);
    if(req.session.captcha === captcha){ // removed Number() here
        res.send({message:'verified'})
    }
    else
        res.send({message: "Not Verified!"})
})

編輯:

看起來像$.ajax發送您必須添加的 cookie

xhrFields: {
  withCredentials: true
},

最終客戶代碼:

$(document).ready(function(){
    $('button').click(function(e){
        var captcha = $('#captcha').val();
        alert(captcha)
        $.ajax({
            url: 'http://localhost:8181/verify-captcha?captcha='+captcha,
            type:'GET',
            xhrFields: {
              withCredentials: true
            },
            success: function(data){
                console.log(data)
            },
            error: function(err) {
                console.error(err);
            }
        })
    })
})

工作示例: https ://stackblitz.com/edit/js-y6dzda(注意:需要在 localhost:8181 上運行的服務器)

似乎您沒有按應有的方式設置會話,請按如下方式更改行:

app.get('/captcha.png', function (request, response) {
var session = request.session; // add this 
if(request.url == '/captcha.png') {
    var randNumber = Math.random()*9000+1000;
    var p = new captchapng(80,30,parseInt(randNumber)); // width,height,numeric captcha
    p.color(0, 0, 0, 0);  // First color: background (red, green, blue, alpha)
    p.color(80, 80, 80, 255); // Second color: paint (red, green, blue, alpha)
    var no  = parseInt(randNumber);
    session.captcha = no.toString(); //change this line
    console.log(parseInt(randNumber));
    console.log(session); // and change this
    var img = p.getBase64();
    var imgbase64 = new Buffer(img,'base64');
    response.writeHead(200, {
        'Content-Type': 'image/png'
    });
    response.end(imgbase64);
} else response.end('');
})

這應該設置會話,因為您將 no.toString() 分配給尚未設置的 request.session.captcha,而存在的是 request.session。

這是一個較舊的問題,但我今天遇到了完全相同的情況。 幾個小時的搜索找到了這個解決方法。

我的環境:

  • 角 CLI:9.1.6
  • 節點:10.16.2
  • 操作系統:win32 x64
  • 角度:9.1.7

如果有更好的方法,請讓所有人知道。 我嘗試過但沒有成功的步驟:

  • 嘗試了 withCredentials: true - 但對我來說也沒有用,因為我啟用了 COR,並且它不允許作為內容保護策略的一部分。
  • 正如 OP 指出的一些我的會話數據是如何隨每個請求發送的(每次“未定義”)

這一切都取決於您計划驗證碼的方式(在這種特殊情況下)在我的情況下 - 我正在使用 sessionStore(請求的一部分),其中包含從用戶角度來看所有會話的列表。 每次嘗試都被視為一個會話。 對於登錄屏幕,我總是考慮使用最后一個 - 但每種情況可能會有所不同。

我最終做的是迭代並從列表中選擇最后一項,我確實得到了驗證碼數據元素。

var captchaFromUser = "";
    if(req.sessionStore){
        if(req.sessionStore.sessions){
            var idKeys = Object.keys(req.sessionStore.sessions);
            if(req.sessionStore.sessions[idKeys[idKeys.length-1]]){
                 captchaFromUser =
                 JSON.parse(req.sessionStore.sessions[idKeys[idKeys.length-1]]).captcha;
            }
        }

    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM