복붙노트

[REDIS] 어떻게 레디 스를 사용하여 NodeJs와 PHP 사이에 공유 세션에?

REDIS

어떻게 레디 스를 사용하여 NodeJs와 PHP 사이에 공유 세션에?

나는 NodeJs 응용 프로그램 및 레디 스를 사용하여 PHP 응용 프로그램 사이의 서버 세션을 공유하고자합니다. 나는이 요지 대부분의 코드를했다.

NodeJs 코드 :

app.use(session({
    store: new RedisStore({prefix: 'session:php:'}),
    name: 'PHPSESSID',
    secret: 'node.js'
}));

app.use(function(req, res, next) {
    req.session.nodejs = 'node.js!';
    res.send(JSON.stringify(req.session, null, '  ') );

});

그리고 출력 :

{
    "cookie": {
        "originalMaxAge": null,
        "expires": null,
        "httpOnly": true,
        "path": "/"
    },
    "passport": {},
    "nodejs": "node.js!"
}

PHP 코드 (나는 레디 스 세션 - PHP와 Predis 사용) :

require('redis-session-php/redis-session.php');
RedisSession::start();

$_SESSION['php'] = 'php';

if (!isset($_SESSION["cookie"])) {
    $_SESSION["cookie"] = array();
}

var_dump($_SESSION);

그리고 출력 :

array(2) {
    ["php"] => string(3) "php"
    ["cookie"] => array(0) { }
}

문제 : 나는 두 세션이 같은 모습을 기대하지만, 그들은 (앱이 동일한 도메인에서 실행)하지 않습니다. Predis \ 클라이언트에서 설정 ()로 값을 설정하면 작동합니다 (그러나 값은 세션 변수에되지 않습니다). 나는 세트 ()를 사용하여 () 얻을, 내가 일을 할 생각이 코드를 발견,하지만 난 그것을 코드를 복잡하게한다고 생각합니다.

당신은 내가 잘못을하고있는 중이 야 뭔지 알아?

해결법

  1. ==============================

    1.나는 요점의 저자입니다. 특급 세션 서명 쿠키를 강제로 시작하고 다른 방식에서 구현하기 시작할 때까지의 코드는했다.

    나는 요점의 저자입니다. 특급 세션 서명 쿠키를 강제로 시작하고 다른 방식에서 구현하기 시작할 때까지의 코드는했다.

    나는 특급 세션의 최신 버전으로 작업에 요점을 업데이트했습니다. 요점의 사본은 편의를 위해 다음과 같습니다 :

    app.js :

    var express = require('express'),
        app = express(),
        cookieParser = require('cookie-parser'),
        session = require('express-session'),
        RedisStore = require('connect-redis')(session);
    
    app.use(express.static(__dirname + '/public'));
    app.use(function(req, res, next) {
      if (~req.url.indexOf('favicon'))
        return res.send(404);
      next();
    });
    app.use(cookieParser());
    app.use(session({
      store: new RedisStore({
        // this is the default prefix used by redis-session-php
        prefix: 'session:php:'
      }),
      // use the default PHP session cookie name
      name: 'PHPSESSID',
      secret: 'node.js rules',
      resave: false,
      saveUninitialized: false
    }));
    app.use(function(req, res, next) {
      req.session.nodejs = 'Hello from node.js!';
      res.send('<pre>' + JSON.stringify(req.session, null, '    ') + '</pre>');
    });
    
    app.listen(8080);
    

    app.php :

    <?php
    // this must match the express-session `secret` in your Express app
    define('EXPRESS_SECRET', 'node.js rules');
    
    // ==== BEGIN express-session COMPATIBILITY ====
    // this id mutator function helps ensure we look up
    // the session using the right id
    define('REDIS_SESSION_ID_MUTATOR', 'express_mutator');
    function express_mutator($id) {
      if (substr($id, 0, 2) === "s:")
        $id = substr($id, 2);
      $dot_pos = strpos($id, ".");
      if ($dot_pos !== false) {
        $hmac_in = substr($id, $dot_pos + 1);
        $id = substr($id, 0, $dot_pos);
      }
      return $id;
    }
    // check for existing express-session cookie ...
    $sess_name = session_name();
    if (isset($_COOKIE[$sess_name])) {
      // here we have to manipulate the cookie data in order for
      // the lookup in redis to work correctly
    
      // since express-session forces signed cookies now, we have
      // to deal with that here ...
      if (substr($_COOKIE[$sess_name], 0, 2) === "s:")
        $_COOKIE[$sess_name] = substr($_COOKIE[$sess_name], 2);
      $dot_pos = strpos($_COOKIE[$sess_name], ".");
      if ($dot_pos !== false) {
        $hmac_in = substr($_COOKIE[$sess_name], $dot_pos + 1);
        $_COOKIE[$sess_name] = substr($_COOKIE[$sess_name], 0, $dot_pos);
    
        // https://github.com/tj/node-cookie-signature/blob/0aa4ec2fffa29753efe7661ef9fe7f8e5f0f4843/index.js#L20-L23
        $hmac_calc = str_replace("=", "", base64_encode(hash_hmac('sha256', $_COOKIE[$sess_name], EXPRESS_SECRET, true)));
        if ($hmac_calc !== $hmac_in) {
          // the cookie data has been tampered with, you can decide
          // how you want to handle this. for this example we will
          // just ignore the cookie and generate a new session ...
          unset($_COOKIE[$sess_name]);
        }
      }
    } else {
      // let PHP generate us a new id
      session_regenerate_id();
      $sess_id = session_id();
      $hmac = str_replace("=", "", base64_encode(hash_hmac('sha256', $sess_id, EXPRESS_SECRET, true)));
      // format it according to the express-session signed cookie format
      session_id("s:$sess_id.$hmac");
    }
    // ==== END express-session COMPATIBILITY ====
    
    
    
    require('redis-session-php/redis-session.php');
    RedisSession::start();
    
    $_SESSION["php"] = "Hello from PHP";
    if (!isset($_SESSION["cookie"]))
      $_SESSION["cookie"] = array();
    
    echo "<pre>";
    echo json_encode($_COOKIE, JSON_PRETTY_PRINT);
    echo json_encode($_SESSION, JSON_PRETTY_PRINT);
    echo "</pre>";
    
    ?>
    
  2. from https://stackoverflow.com/questions/27966754/how-to-share-session-between-nodejs-and-php-using-redis by cc-by-sa and MIT license