Saya mencoba membuat mekanisme login menggunakan node.js, express, dan passport.js. Login itu sendiri berfungsi cukup bagus, juga sesi disimpan dengan baik dengan redis tetapi saya memiliki beberapa masalah dengan mengarahkan pengguna ke tempat dia memulai sebelum diminta untuk mengotentikasi.
mis. Tautan mengikuti pengguna http://localhost:3000/hidden
kemudian dialihkan ke http://localhost:3000/login
tetapi kemudian saya ingin dia dialihkan lagi ke http://localhost:3000/hidden
.
Tujuannya adalah, jika pengguna mengakses secara acak halaman yang dia butuhkan untuk masuk terlebih dahulu, dia akan dialihkan ke situs / login dengan memberikan kredensial dan kemudian dialihkan kembali ke situs yang sebelumnya dia coba akses.
Ini posting login saya
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);
});
dan di sini Metode sureAuthenticated saya
function ensureAuthenticated (req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login');
}
yang terhubung ke /hidden
halaman
app.get('/hidden', ensureAuthenticated, function(req, res){
res.render('hidden', { title: 'hidden page' });
});
Output html untuk situs login cukup sederhana
<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>
Jawaban:
Saya tidak tahu tentang paspor, tapi begini cara saya melakukannya:
Saya memiliki middleware yang saya gunakan dengan
app.get('/account', auth.restrict, routes.account)
set ituredirectTo
di sesi ... lalu saya mengarahkan ke / loginKemudian di
routes.login.post
saya lakukan hal berikut:sumber
req.session.redirect_to = req.path
req.session.redirect_to = req.path
di dalam middleware auth Anda. Kemudian baca dan hapus dilogin.post
rute.Dalam
ensureAuthenticated
metode Anda, simpan url kembali dalam sesi seperti ini:Kemudian Anda dapat memperbarui passport.authenticate rute Anda ke sesuatu seperti:
sumber
req.session.returnTo = null;
Lihat pertanyaan ini untuk info tambahan tentang logout default paspor, yang, pada pemeriksaan sumber, tampaknya hanya menghapus session.user, dan bukan seluruh sesi.req.path
saya akan menggunakanreq.originalUrl
karena ini adalah kombinasi baseUrl dan path, lihat dokumentasinyaLihatlah connect-sure-login , yang bekerja di samping Passport untuk melakukan apa yang Anda inginkan!
sumber
Cara saya melakukan sesuatu:
GET / pengontrol login :
Pengontrol POST / login :
Pengontrol POST / logout (tidak yakin apakah ada 100% ok, komentar dipersilakan):
Hapus returnTo middleware (hapus returnTo dari sesi di rute mana pun kecuali rute auth - bagi saya mereka adalah / login dan / auth /: provider):
Pendekatan ini memiliki dua fitur :
sumber
Jika Anda menggunakan connect-sure-login, ada cara super-mudah dan terintegrasi untuk melakukan ini dengan Passport menggunakan
successReturnToOrRedirect
parameter. Saat digunakan, paspor akan mengirim Anda kembali ke URL yang diminta semula atau kembali ke URL yang Anda berikan.https://github.com/jaredhanson/connect-ensure-login#log-in-and-return-to
sumber
Jawaban @chovy dan @linuxdan memiliki bug dengan tidak membersihkan
session.returnTo
jika pengguna pergi ke halaman lain setelah pengalihan login (itu tidak memerlukan otentikasi) dan masuk melalui sana. Jadi tambahkan kode ini ke implementasinya:Jika Anda melakukan beberapa permintaan ajax dari halaman login, Anda juga dapat mengecualikannya.
Pendekatan lainnya adalah dengan menggunakan flash in
ensureAuthenticated
Dan kemudian di GET login
Dalam tampilan tambahkan bidang tersembunyi ke formulir login (contoh di giok)
Dalam login POST
Perhatikan bahwa redirectTo akan dihapus setelah GET login terlebih dahulu.
sumber
Cara termudah (dan benar) untuk mencapai ini adalah pengaturan
failureRedirect
dansuccessRedirect
opsi .sumber
successRedirect
sedang digunakan pada rute pulang, tapi kemudian tujuan yang dimaksud (yaitu direturnTo
atas) akan hilang, bukan?