2012-01-30 11 views
11

मेरे पास एक एकल नोड सर्वर है जो अनुरोधों का जवाब देता है और होस्ट हेडर पर आधारित उपयोगकर्ता को रीडायरेक्ट करता है। उपयोग यह है कि स्थैतिक/होम साइट www पर रहती है और प्रत्येक उपयोगकर्ता का अपना उप डोमेन होता है (यानी www.example.com और site.example.com)। रूटिंग साइट.जे.एस. के अनुसार है।एक्सप्रेस और नोड का उपयोग, सबडोमेन/होस्टहेडर में सत्र को बनाए रखने के लिए कैसे करें

जब उपयोगकर्ता लॉग इन नहीं होता है तो उन्हें लॉगिन करने के लिए रीडायरेक्ट किया जाता है।

मुझे पता चल रहा है कि जब उपयोगकर्ता को उनके उप डोमेन पर रीडायरेक्ट किया जाता है तो सत्र बनाए रखा नहीं जाता है। मुझे लगता है कि यह उम्मीद की जा रही है, लेकिन मैं सोच रहा हूं कि दोनों उप डोमेनों में एक ही सत्र को बनाए रखने का कोई तरीका है या नहीं।

मैं उम्मीद कर रहा था कि अगर वे लॉग इन होते हैं और www.example.com पर लौटते हैं तो वे एक अलग दृश्य देखेंगे जिसमें लॉगआउट/उनके डैशबोर्ड आदि का एक लिंक शामिल था। इस समय मेरा कामकाज, मैं सोच रहा हूं, सिर्फ अपने सबडोमेन पर सत्र बनाना है और यदि वे www पर वापस आते हैं तो यह ऐसा होगा जैसे वे लॉग इन नहीं हैं।

किसी ने इस से पहले इस तरह से निपटाया है या इस तरह से सत्रों को संभालने के तरीके के बारे में जवाब दिया है?

मुझे लगता है कि इस मुद्दे को users.js में हो सकता है, जहां मैं अपने नहीं एक रिश्तेदार पथ के रूप में पुन: निर्देशित करने 'http://site.example.com' ...

यहाँ प्रासंगिक कोड है (उपयोगकर्ता देखने MongoDB का उपयोग किया जाता है और मैं अपने ठीक काम कर रहा है क्योंकि यह बाहर छोड़ दिया गया है - लाइन कि इस सेवा कॉल users.authenticate) है ...

server.js:

app.configure -> 
app.set "views", "#{__dirname}/views" 
app.set "view engine", "jade" 
app.use express.bodyParser() 
app.use express.methodOverride() 
app.use express.cookieParser() 
app.use express.session { 
    key: "KEY", 
    secret: "SECRET", 
    store: new MemoryStore(), 
    cookie: { 
     domain: 'example.com', 
     maxAge : 1000*60*60*24*30*12 
    } 
} 
app.use express.static "#{__dirname}/public" 
app.use express.logger "short" 
app.use express.favicon "#{__dirname}/public/img/favicon.ico" 
app.use app.router 

site.js:

module.exports = (app) -> 
app.get '/', (req, res) -> 
    console.log "/ hit with #{req.url} from #{req.headers.host}" 
    domains = req.headers.host.split "." 
    org = if domains then domains[0] else "www" 
    if org == "www" 
     res.render "index", { layout: null } 
    else 
     if req.session.user 
      console.log "session established" 
      res.render "app", { layout: null } 
     else 
      console.log "no session" 
      res.redirect "http://www.example.com/accounts/login"  

users.js:

users = require('../services/users') 
module.exports = (app) -> 
app.get "/accounts/login", (req, res) -> 
    res.render "login", { layout: null, locals: { returnUrl: req.query.returnUrl } } 
app.post "/accounts", (req, res) -> 
    users.authenticate app, req.body.login, req.body.password, (user) -> 
     if user 
      req.session.user = user 
      res.redirect "http://#{user.orgName}.example.com" 
     else 
      res.render "login", { layout: null, locals: { returnUrl: req.body.url } } 
app.get "/accounts/logout", (req, res) -> 
    console.log "deleting user from session" 
    delete req.session.user 
    res.redirect "http://www.example.com     

पर OSX स्थानीय स्तर पर यह परीक्षण करने के लिए, मैं www.example.com और site.example.com में मेरी होस्ट फ़ाइल से इतना है कि DNS खोज के स्थानीय रूप से नियंत्रित किया हो जोड़ लिया है।

उत्तर

23

ब्राउजर को क्रॉस-डोमेन अनुरोध करने की अनुमति देने के लिए सबसे पहले आपको सर्वर की तरफ हेडर सेट करने की आवश्यकता है। यह समाधान सामान्य अनुरोध के साथ ही AJAX के लिए काम करता है। अपने एक्सप्रेस कॉन्फ़िगर समारोह में:

एक्सप्रेस 4.0:

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

var app = express(); 

app.use(cookieParser()); 
app.use(session({ 
    secret: 'yoursecret', 
    cookie: { 
     path: '/', 
     domain: 'yourdomain.com', 
     maxAge: 1000 * 60 * 24 // 24 hours 
    } 
})); 
app.use(function(req, res, next) { 
    res.header('Access-Control-Allow-Credentials', true); 
    res.header('Access-Control-Allow-Origin', req.headers.origin); 
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE'); 
    res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept'); 
    next(); 
}); 

पहुंच-नियंत्रण-अनुमति दें-उत्पत्ति '*' के लिए सेट किया जा सकता है, तो सत्र के लिए क्रॉस-डोमेन कुकीज़ विनिमय की जरूरत है। कुकीज़ और सत्र साझा करने के लिए क्रॉस-डोमेन साझा करने के लिए आपको वास्तव में डोमेन पर विशिष्ट एक्सेस-कंट्रोल-अनुमति-उत्पत्ति सेट करने की आवश्यकता है, जहां से अनुरोध किया गया है, यही कारण है कि req.headers.origin - इसके लिए बिल्कुल सही है।

डोमेन का उपयोग करना यह स्थानीयहोस्ट पर अच्छी तरह से काम नहीं करेगा - इसलिए सुनिश्चित करें कि आप इसे विकास पर्यावरण में अक्षम कर दें, और उत्पादन पर सक्षम हों। यह शीर्ष और उप डोमेन में साझा कुकीज़ को सक्षम करेगा।

यह सब कुछ नहीं है। ब्राउज़र स्वयं क्रॉस डोमेन अनुरोधों पर कुकीज़ नहीं भेजेंगे, और इसे मजबूर होना होगा। jQuery में आप $ .ajax में अतिरिक्त पैरामीटर जोड़ सकते हैं() अनुरोध:

xhrFields: { withCredentials: true } 

गैर jQuery के लिए, बस एक्सएचआर निर्माता है और इस पैरामीटर सेट:

xhr.withCredentials = true; 

और तुम पार करने के लिए तैयार कर रहे हैं साझा सत्र के साथ -डोमेन।

+1

उपयोगकर्ता '$ .ajaxSetup' को प्रत्येक अनुरोध के लिए' प्रमाण पत्र: सत्य 'जोड़ने के लिए – Xerri

+0

@Maksims "डोमेन का उपयोग करना यह स्थानीयहोस्ट पर अच्छी तरह से काम नहीं करेगा" - यह स्थानीयहोस्ट पर क्यों काम नहीं करता है? मेरे पास है: api.localhost: 3000 और localhost: 3000 - काम नहीं कर रहा है? : \ – AmpT

+0

क्योंकि ब्राउज़र की सुरक्षा से कुकी चालू नहीं की जाएगी यदि वर्तमान डोमेन अपने परिभाषित डोमेन से मेल नहीं खाता है। विकास और मंच वातावरण के लिए आप डोमेन संपत्ति पर टिप्पणी कर सकते हैं, या इसे "लोकलहोस्ट" पर सेट कर सकते हैं। – moka

2

क्या आप सुनिश्चित करते हैं कि आपकी कुकीज़ शीर्ष-स्तरीय डोमेन पर सेट है, तो इसे सभी सबडोमेन द्वारा पढ़ा जा सकता है? फिर यह सिर्फ एक मामला है या स्मृति में आपके सत्र डेटा को जारी रखता है, एक डीबी, जो भी सामान्य है। मेरे पास मेरी देव मशीन नहीं है और चल रही है, लेकिन यह आपके app.configure() में ऐसा कुछ होगा।

app.use(express.cookieParser()); 

app.use(express.session({ 
    key: 'A_SESSION_KEY', 
    secret: 'SOMETHING_REALLY_HARD_TO_GUESS', 
    store: new express.session.MemoryStore, 
    cookie: { 
    path  : '/', 
    domain : 'yourdomain.com', 
    httpOnly : true, 
    maxAge : 1000*60*60*24*30*12 //one year(ish) 
    } 
})); 
+1

मैंने आपके सुझाव में जोड़ा है लेकिन इससे कोई फर्क नहीं पड़ता है। मैंने 'example.com', '* .example.com', और '.example.com' की कोशिश की। मैंने प्रक्रिया को थोड़ा बेहतर तरीके से विस्तारित करने के लिए अपने मूल प्रश्न में और कोड जोड़ा है। मुझे लगता है कि यह रीडायरेक्ट के साथ एक मुद्दा हो सकता है ... – mattgi

+0

@mattgi अपना कोड बदलने के बाद अपने ब्राउज़र में सभी कुकीज़ को निकालने का प्रयास करें। यह जवाब मेरे लिए अच्छा लगता है। – InspiredJW

+0

@InspiredJW ने ऐसा किया है .. शायद ऐसा इसलिए क्योंकि मैं स्थानीय रूप से चल रहा हूं? जब मैं session.user = user सेट करता हूं और फिर कंसोल पर सत्र को लॉग करता हूं तो मैं इसे वहां देख सकता हूं, लेकिन जिस पल में मैं रीडायरेक्ट करता हूं, वह गायब हो जाता है .. वास्तव में यह उप डोमेन 'समस्या' से असंबंधित हो सकता है, मैं कोशिश कर रहा हूं हल करें क्योंकि ऐसा लगता है कि मेरा सत्र बस किसी भी मार्ग पर काम नहीं कर रहा है (यहां तक ​​कि एक ही होस्ट हेडर पर)। – mattgi

0

नोट: यदि एक्सप्रेस 4 और नई कुकी सत्र मॉड्यूल का उपयोग कर, कोड लग रहा है

तरह
{ 
    secret: <session_secret> , 
    store: <session store> , 
    domain: '.domain.com', 
} 

यह मैं थोड़ा है, लेकिन एपीआई बदल गया है।

संबंधित मुद्दे