Bagaimana cara mengetahui apakah pengguna login dengan passport.js?

104

Saya telah membaca passport.jsinfo dan sampel selama dua hari, tetapi saya tidak yakin setelah itu saya melakukan semua proses otentikasi.

Bagaimana saya tahu jika saya sedang masuk, misalnya, saya akan memiliki bilah navigasi dengan tombol masuk atau keluar, apakah ada variabel seperti kode di bawah ini?

if (login)
   <button>logout</button>
else 
   <button>login</button>
RMontes13
sumber

Jawaban:

210

Jika pengguna masuk, passport.jsakan membuat userobjek masuk requntuk setiap permintaan masuk express.js, yang dapat Anda periksa keberadaannya di middleware manapun:

if (req.user) {
    // logged in
} else {
    // not logged in
}

Anda dapat membuat express.jsmiddleware sederhana untuk itu, yang akan memeriksa apakah pengguna login, dan jika tidak - akan dialihkan ke /loginhalaman:

function loggedIn(req, res, next) {
    if (req.user) {
        next();
    } else {
        res.redirect('/login');
    }
}

Dan gunakan itu:

app.get('/orders', loggedIn, function(req, res, next) {
    // req.user - will exist
    // load user orders and render them
});
moka
sumber
Ini global? Bisakah saya mengaksesnya di semua proyek setelah login?
RMontes13
3
itu tidak global hanya pada objek permintaan.
supernova
1
Dalam 98,8% pengembangan web dengan express.js dan passport.js, Anda akan menangani permintaan (app.get, app.post, dll), jadi berbicara tentang penggunaan passport.js di luarnya sedikit tidak berguna. Ya, itu hanya dalam penangan middleware rute ekspres seperti app.get, app.postdll. Jika Anda memerlukan fungsionalitas yang berbeda, maka Anda harus menjelaskannya secara rinci dalam pertanyaan Anda serta apa yang ingin Anda capai.
moka
2
Saya menemukan bahwa jika saya tidak menyediakan router.get () dengan middleware apapun untuk memeriksa otentikasi, seperti dalam "router.get ('/', my_controller.index)", maka paspor tidak pernah dikonsultasikan dan req.user akan selalu menjadi tidak terdefinisi. Ini membuat frustrasi karena saya ingin mengizinkan pengunjung mana pun untuk memanggil API, tetapi menyesuaikan konten tanggapan tergantung pada siapa yang meminta.
Lawrence I. Siden
2
Adakah yang bisa menjelaskan bagaimana ini tidak bisa dieksploitasi? Pemeriksaan itu hanya melihat apakah mereka adalah objek pengguna dalam permintaan. Dimana validasi sesinya?
rambossa
46

Jika Anda ingin menggunakannya di template Anda karena sampel kode Anda sepertinya menunjukkan bahwa Anda dapat membuat beberapa middleware seperti ini:

app.use(function (req, res, next) {
  res.locals.login = req.isAuthenticated();
  next();
});

Letakkan kode itu di suatu tempat setelah Anda menyiapkan paspor.

Dan kemudian gunakan di template Anda (contoh swig)

{% if login %}
<button>logout</button>
{% else %} 
<button>login</button>
{% endif %}
cyberwombat
sumber
Untuk beberapa alasan middleware di atas memberi saya masalah dengan pengguna yang tidak ditentukan dalam template saya. Saya harus memasok kembali objek pengguna ke tampilan untuk memperbaikinya seperti ini: app.use(function(req,res,next){ res.locals.login = req.isAuthenticated(); res.locals.user = req.user; next(); });
Tebbers
Bahkan setelah otentikasi berhasil, isAuthenticatedmemberikan false di permintaan berikutnya. Bisakah Anda membantu menjawab pertanyaan ini stackoverflow.com/questions/42842171/…
Suhail Gupta
3

Hal ini tidak secara eksplisit didokumentasikan tetapi ada isAuthenticated()metode yang dimasukkan ke dalam reqoleh paspor .
Dapat digunakan sebagai berikut,

req.isAuthenticated() // returns true if auth, false if not

// auth.js
module.exports = {
  ensureAuthenticated: (req, res, next) => {
    if (req.isAuthenticated()) {
      return next()
    }
    res.redirect('/login') // if not auth
  },

  forwardAuthenticated: (req, res, next) => {
    if (!req.isAuthenticated()) {
      return next()
    }
    res.redirect('/dashboard');  // if auth    
  }
}

// app.js
app.get('/dashboard', ensureAuthenticated, (req, res) => res.render('dashboard'))
app.get('/login', forwardAuthenticated, (req, res) => res.render('login'))
app.get('/register', forwardAuthenticated, (req, res) => res.render('register'))
Hasan Sefa Ozalp
sumber
2

Saya sedang mencari solusi tersebut dan menemukan halaman ini. Pertanyaannya adalah bagaimana cara memeriksa status login di sisi klien.

Setelah login saya menyembunyikan tombol Login dan menampilkan tombol logout. Pada halaman refresh saya kembali melihat tombol login, bukan tombol logout. Satu-satunya solusi adalah menyimpan item di sessionStorage jika Anda menggunakan session (dan localStorage jika Anda menggunakan JWT). Hapus item ini saat Anda keluar. Kemudian di setiap pemuatan halaman periksa item sessionStorage ini dan lakukan yang sesuai.

if (sessionStorage.getItem('status')) {
    $("#btnlogout").show();
    $("#btnlogin").hide();
// or what ever you want to do
} else {
    $("#btnlogout").hide();
    $("#btnlogin").show();
}



function Login() {
            var data = {
                username: $("#myModal #usr").val(),
                password: $("#myModal #pw").val()

            };
            $.ajax({
                type: 'POST',
                url: '/login',
                contentType: 'application/JSON; charset=utf-8',
                data: JSON.stringify(data),
                success: funcSuccess,
                error: funcFail
            });
            function funcSuccess(res) {
                sessionStorage.setItem('status', 'loggedIn');

                $("#btnlogout").show();
                $("#btnlogin").hide();
            }
            function funcFail() { $("#pp").text('Login Failed'); };
        };

function Logout() {
    $.ajax({
        type: 'GET',
        url: '/logout',
        contentType: 'application/JSON; charset=utf-8',
        success: funcSuccess,
        error: funcFail,
    });
    function funcSuccess(res) {
        $("#btnlogout").hide();
        $("#btnlogin").show();
        sessionStorage.removeItem("status");
    };
    function funcFail() { alert('Login method Failed'); };
}; 
Zeni
sumber
2

gunakan kode di bawah ini di dalam app.get () atau router.get ()

router.get('/edit/:id', (req, res)=>{
  if(req.isAuthenticated()){
     if(req.isAuthenticated()){
      //

      }
  else{
   res.redirect('/users/login');//your particular login routes
     }
});
Pankaj
sumber
0

Pertanyaan bagus, saya mengalami beberapa masalah saat mencoba menerapkan sesuatu seperti ini, ketika ada permintaan yang tidak diautentikasi, setang melewatkan blok if jika variabel res.locals mengembalikan nilai yang salah. Untuk mengatasi masalah ini, Anda perlu menyiapkan middleware di file app.js Anda untuk membuat req.user tersedia secara global di aplikasi Anda. Seperti ..

app.use(function (req, res, next) {
res.locals.login = req.user;
next();

});

Di file header Anda, Anda dapat melakukan pemeriksaan ini untuk pengguna yang diautentikasi dan menampilkan konten yang sesuai seperti itu ..

                {{#if login }}
                    <li><a href="#">User Account</a></li>
                    <li role="separator" class="divider"></li>
                    <li><a href="#">Logout</a></li>
                {{/if}}
                {{#unless login}}
                    <li><a href="#">Sign up</a></li>
                    <li><a href="#">Sign in</a></li>
                {{/unless}} 
Camillus Chinaedu Teteh
sumber