Passport.js का उपयोग करने के बाद नोड में प्रमाणीकरण के बाद पिछले पृष्ठ पर पुनः निर्देशित करें


100

मैं नोड.जेएस, एक्सप्रेस और पासपोर्ट.जेएस का उपयोग करके एक लॉगिन तंत्र स्थापित करने की कोशिश कर रहा हूं। लॉगिन स्वयं काफी अच्छा काम करता है, सत्र भी रेडिस के साथ अच्छी तरह से संग्रहीत किए जाते हैं, लेकिन मुझे उपयोगकर्ता को पुन: निर्देशित करने से कुछ परेशानी होती है, जहां उसे प्रमाणित करने के लिए प्रेरित करने से पहले शुरू किया गया था।

उदाहरण के लिए उपयोगकर्ता इस प्रकार लिंक http://localhost:3000/hiddenको फिर से रीडायरेक्ट किया जाता है, http://localhost:3000/loginलेकिन फिर मैं चाहता हूं कि उसे फिर से रीडायरेक्ट किया जाए http://localhost:3000/hidden

इसका उद्देश्य यह है कि यदि उपयोगकर्ता किसी ऐसे पेज को बेतरतीब ढंग से एक्सेस करता है जिसे उसे पहले लॉग इन करना पड़ता है, तो उसे / क्रेडेंशियल प्रदान करने वाली लॉगिन साइट पर रीडायरेक्ट किया जाएगा और फिर उस साइट पर वापस रीडायरेक्ट किया जा सकता है जिसे उसने पहले एक्सेस करने की कोशिश की थी।

यहाँ मेरा लॉगिन पोस्ट है

app.post('/login', function (req, res, next) {
    passport.authenticate('local', function (err, user, info) {
        if (err) {
            return next(err)
        } else if (!user) { 
            console.log('message: ' + info.message);
            return res.redirect('/login') 
        } else {
            req.logIn(user, function (err) {
                if (err) {
                    return next(err);
                }
                return next(); // <-? Is this line right?
            });
        }
    })(req, res, next);
});

और यहाँ मेरा सुनिश्चित तरीका है

function ensureAuthenticated (req, res, next) {
  if (req.isAuthenticated()) { 
      return next();
  }
  res.redirect('/login');
}

जो /hiddenपृष्ठ में हुक करता है

app.get('/hidden', ensureAuthenticated, function(req, res){
    res.render('hidden', { title: 'hidden page' });
});

लॉगिन साइट के लिए HTML आउटपुट काफी सरल है

<form method="post" action="/login">

  <div id="username">
    <label>Username:</label>
    <input type="text" value="bob" name="username">
  </div>

  <div id="password">
    <label>Password:</label>
    <input type="password" value="secret" name="password">
  </div>

  <div id="info"></div>
    <div id="submit">
    <input type="submit" value="submit">
  </div>

</form>

नमस्ते, मैं भी यही अंतर कर रहा हूं जब उपयोगकर्ता सफलतापूर्वक लॉग इन होता है तो मैं'.html उपयोगकर्ता नाम 'जैसे संदेश के साथ wel.html पृष्ठ पर पुनर्निर्देशित करूंगा। सुना है UserName उसका / उसका LoginName होगा। क्या आप मुझे दिखा सकते हैं कि अगले पेज पर टेक्स्ट बॉक्स वैल्यू कैसे पास करें ??
ध्रूमिल शाह

बहुत कुछ पता नहीं मुझे लगता है कि यह बस से होकर गुजरेगा। मेरे उदाहरण के अनुसार जो हो सकता है: res.render ('छिपा हुआ', {शीर्षक: 'छिपा हुआ पृष्ठ', उपयोगकर्ता नाम: 'Tyrion Lannister'});
Alx

जवाबों:


84

मुझे पासपोर्ट के बारे में पता नहीं है, लेकिन यहां बताया गया है कि मैं यह कैसे करता हूं:

मेरे पास एक मिडलवेयर है जिसे मैं सत्र में app.get('/account', auth.restrict, routes.account)उस सेट के साथ उपयोग करता redirectToहूं ... फिर मैं / लॉगिन पर रीडायरेक्ट करता हूं

auth.restrict = function(req, res, next){
    if (!req.session.userid) {
        req.session.redirectTo = '/account';
        res.redirect('/login');
    } else {
        next();
    }
};

फिर routes.login.postमैं निम्नलिखित कार्य करता हूं:

var redirectTo = req.session.redirectTo || '/';
delete req.session.redirectTo;
// is authenticated ?
res.redirect(redirectTo);

आपके जवाब के लिए धन्यवाद। क्या आप अपने कोड में रीडायरेक्ट / अकाउंट डायरेक्ट सेट नहीं कर रहे हैं? यदि आपके पास एक और लिंक है तो आइए कहते हैं / pro_accounts का उपयोग करते हुए एक ही Cort.restrict का उपयोग करके उन्हें / खाते में पुनः निर्देशित किया जाएगा ....
Alx

4
यह सच है। मैं हमेशा / खाते में पुन: निर्देशित के बाद वे के लिए लॉग इन करें, लेकिन आप के साथ बदलने सकता हैreq.session.redirect_to = req.path
chovy

1
हम्म .. इसके लिए काफी नहीं मैं देख रहा हूँ। मैं यह सुनिश्चित करने के लिए सुनिश्चित करता हूं कि यदि कोई उपयोगकर्ता पहले से ही पंजीकृत है या नहीं, तो यह पता लगाने के लिए कि क्या यह / लॉगिन पर पुनर्निर्देशित है या नहीं। इस दृष्टिकोण से मुझे / अकाउंट में वापस आने के लिए एक तरीका चाहिए। / लॉगिन के भीतर req.path को कॉल करने से मुझे सरल / लॉगिन बैक मिलता है। यदि रेफ़र ठीक से सेट होता है तो रेफ़र का उपयोग करना या तो इसके बहुत अधिक निश्चित रूप से काम नहीं करता है ...
Alx

6
आपको req.session.redirect_to = req.pathअपने सामान्य मिडलवेयर के अंदर सेट करने की आवश्यकता है । फिर इसे पढ़ें और login.postमार्ग में हटा दें ।
चोवै

यह पासपोर्ट के लिए एक महान समाधान नहीं है जो सफलता को स्वीकार करता है अप्रत्यक्ष एक बिंदु पर एक विकल्प के रूप में अनुरोध करता है कि उपलब्ध नहीं है
linuxdan

110

अपनी ensureAuthenticatedविधि में सत्र में रिटर्न यूआरएल को इस तरह सहेजें:

...
req.session.returnTo = req.originalUrl; 
res.redirect('/login');
...

तब आप अपने पासपोर्ट को अपडेट कर सकते हैं।

app.get('/auth/google/return', passport.authenticate('google'), function(req, res) {
    res.redirect(req.session.returnTo || '/');
    delete req.session.returnTo;
}); 

7
पहले पास पर काम किया है, लेकिन मुझे पासपोर्ट में रीडायरेक्ट के बाद निम्नलिखित जोड़ने की जरूरत है। बाद में लॉगआउट / लॉगिन के बाद रिटर्न पते पर वापस जाने से बचने के लिए जटिल मार्ग: पासपोर्ट के डिफ़ॉल्ट लॉगआउट के बारे में अतिरिक्त जानकारी के लिए यह प्रश्नreq.session.returnTo = null; देखें , जो, स्रोत की जांच पर, केवल सत्र स्पष्ट करने के लिए लगता है।
रॉब एंड्रेन

क्या मैं सत्र के बजाय कॉलबैक = / प्रोफाइल के आसपास बस पास कर सकता हूं
OMGPOP

@OMGPOP आप शायद कर सकते हैं, लेकिन यह बहुत सुरक्षित नहीं है, क्या कोई कारण है कि आप सत्र का लाभ नहीं लेना चाहते हैं?
linuxdan

@linuxdan बिल्कुल नहीं। लेकिन यह केवल पुनर्निर्देशित लिंक को बाहर निकालने और सत्र में डालने के लिए परेशानी भरा है, तब जब उपयोगकर्ता पुनर्निर्देशित करता है, तो सत्र से अनुप्रेषित लिंक को वापस असाइन करें
OMGPOP

5
इसके बजाय req.pathमैं इसका उपयोग करूंगा req.originalUrlक्योंकि यह बेसयूएल और पथ का एक संयोजन है, दस्तावेज़ीकरण
मैथ्यूस


7

मेरा काम करने का तरीका:

const isAuthenticated = (req, res, next) => {
  if (req.isAuthenticated()) {
    return next()
  }
  res.redirect( `/login?origin=${req.originalUrl}` )
};

GET / लॉगिन नियंत्रक:

if( req.query.origin )
  req.session.returnTo = req.query.origin
else
  req.session.returnTo = req.header('Referer')

res.render('account/login')

पोस्ट / लॉगिन नियंत्रक:

  let returnTo = '/'
  if (req.session.returnTo) {
    returnTo = req.session.returnTo
    delete req.session.returnTo
  }

  res.redirect(returnTo);

POST / लॉगआउट कंट्रोलर (सुनिश्चित नहीं है कि 100% ठीक है, टिप्पणियाँ स्वागत हैं):

req.logout();
res.redirect(req.header('Referer') || '/');
if (req.session.returnTo) {
  delete req.session.returnTo
}

क्लियर रिटर्नटू मिडलवेयर (किसी भी रूट पर सत्र से वापसी का रास्ता साफ कर देता है - मेरे लिए वे रूट / लॉगिन और / / / प्रदाता हैं:)

String.prototype.startsWith = function(needle)
{
  return(this.indexOf(needle) == 0)
}

app.use(function(req, res, next) {
  if ( !(req.path == '/login' || req.path.startsWith('/auth/')) && req.session.returnTo) {
    delete req.session.returnTo
  }
  next()
})

इस दृष्टिकोण में दो विशेषताएं हैं :

  • आप isuthenticated मिडलवेयर के साथ कुछ मार्गों की रक्षा कर सकते हैं ;
  • किसी भी पृष्ठ पर आप बस लॉगिन URL पर क्लिक कर सकते हैं, और उस पृष्ठ पर लॉगिन वापसी के बाद ;

यहां बहुत सारी अच्छी प्रतिक्रियाएं मिलीं, मैं आपके उदाहरण का उपयोग करने में सक्षम था और इसने मेरी परियोजना के साथ काम किया। धन्यवाद!
user752746

5

यदि आप कनेक्ट-सुनिश्चित-लॉगिन का उपयोग कर रहे हैं तो successReturnToOrRedirectपैरामीटर का उपयोग करके पासपोर्ट के साथ ऐसा करने के लिए एक सुपर-आसान, एकीकृत तरीका है । जब उपयोग किया जाता है, तो पासपोर्ट आपको मूल रूप से अनुरोधित URL पर वापस भेज देगा या आपके द्वारा प्रदान किए गए URL पर वापस आ जाएगा।

router.post('/login', passport.authenticate('local', {
  successReturnToOrRedirect: '/user/me',
  failureRedirect: '/user/login',
  failureFlash: true
}));

https://github.com/jaredhanson/connect-ensure-login#log-in-and-return-to


ऐसा लगता है जैसे @ jaredhanson के जवाब की नकल
mikemaccana

1

@chovy और @linuxdan के उत्तर बग क्लियर नहीं होते हैं session.returnToयदि उपयोगकर्ता लॉगिन रीडायरेक्ट के बाद किसी अन्य पेज पर जाता है ( अर्थात प्रमाणीकरण की आवश्यकता नहीं है) और वहां से लॉगइन करता है। इसलिए इस कोड को उनके कार्यान्वयन में जोड़ें:

// clear session.returnTo if user goes to another page after redirect to login
app.use(function(req, res, next) {
    if (req.path != '/login' && req.session.returnTo) {
        delete req.session.returnTo
    }
    next()
})

यदि आप लॉगिन पेज से कुछ अजाक्स अनुरोध करते हैं, तो आप उन्हें बाहर भी कर सकते हैं।


एक अन्य तरीका यह है कि फ्लैश का उपयोग किया जाएensureAuthenticated

req.flash('redirectTo', req.path)
res.redirect('/login')

और फिर GET लॉगिन करें

res.render('login', { redirectTo: req.flash('redirectTo') })

देखने के लिए लॉगिन फ़ॉर्म में छिपा हुआ क्षेत्र जोड़ें (उदाहरण जेड में)

if (redirectTo != '')
    input(type="hidden" name="redirectTo" value="#{redirectTo}")

POST लॉगिन में

res.redirect(req.body.redirectTo || '/')

ध्यान दें कि इसके साथ पहले GET लॉगिन के बाद रीडायरेक्ट स्पष्ट हो जाएगा।


0

इसे प्राप्त करने के लिए सबसे आसान (और ठीक से) तरीका सेटिंग failureRedirectऔर successRedirectविकल्प है


क्या आप विस्तार से समझा सकते हैं? मैं successRedirectवापसी मार्ग पर उपयोग होते हुए देख सकता हूं , लेकिन तब इच्छित गंतव्य (यानी returnToऊपर) खो जाएगा, है ना?
टॉम सोडरलंड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.