Jak sprawdzić, czy użytkownik jest zalogowany za pomocą paszsport.js?

104

Czytam passport.jsinformacje i próbki przez dwa dni, ale nie jestem pewien, czy później wykonałem cały proces uwierzytelniania.

Skąd mam wiedzieć, czy jestem zalogowany, na przykład mam pasek nawigacyjny z przyciskiem logowania lub wylogowania, czy jest jakaś zmienna, taka jak kod poniżej?

if (login)
   <button>logout</button>
else 
   <button>login</button>
RMontes13
źródło

Odpowiedzi:

210

Jeśli użytkownik jest zalogowany, passport.jsutworzy userobiekt reqdla każdego żądania w express.js, który możesz sprawdzić w dowolnym oprogramowaniu pośrednim:

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

Możesz w tym celu stworzyć proste express.jsoprogramowanie pośredniczące, które sprawdzi, czy użytkownik jest zalogowany, a jeśli nie - przekieruje na /loginstronę:

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

I użyj go:

app.get('/orders', loggedIn, function(req, res, next) {
    // req.user - will exist
    // load user orders and render them
});
moka
źródło
Czy jest globalny? Czy mogę uzyskać do niego dostęp we wszystkich projektach po zalogowaniu?
RMontes13
3
nie jest globalny, jest tylko w obiekcie żądania.
supernowa
1
W 98,8% tworzenia stron internetowych za pomocą express.js i passport.js będziesz zajmować się żądaniami (app.get, app.post itp.), Więc mówienie o używaniu passport.js poza nim jest trochę bezcelowe. Tak to tylko w ciągu ekspresowych koparki middleware trasa podoba app.get, app.postitd. Jeśli potrzebujesz inną funkcjonalność, to należy wyjaśnić szczegółowo w swoim pytaniu, jak również to, co staramy się osiągnąć.
moka
2
Zauważyłem, że jeśli nie dostarczę router.get () żadnego oprogramowania pośredniego do sprawdzania uwierzytelnienia, jak w "router.get ('/', my_controller.index)", to paszport nigdy nie jest sprawdzany, a req.user zawsze być niezdefiniowane. To frustrujące, ponieważ chcę umożliwić każdemu odwiedzającemu wywołanie interfejsu API, ale dostosowuję treść odpowiedzi w zależności od tego, kto prosi.
Lawrence I. Siden
2
Czy ktoś może wyjaśnić, dlaczego nie można tego wykorzystać? To sprawdzenie po prostu sprawdza, czy w żądaniu jest obiektem użytkownika. Gdzie jest walidacja sesji?
rambossa
46

Jeśli chcesz użyć go w swoich szablonach, ponieważ przykładowy kod wydaje się wskazywać, możesz utworzyć oprogramowanie pośredniczące, takie jak to:

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

Umieść ten kod gdzieś po skonfigurowaniu paszportu.

A następnie użyj go w swoim szablonie (przykład swig)

{% if login %}
<button>logout</button>
{% else %} 
<button>login</button>
{% endif %}
cyberwombat
źródło
Z jakiegoś powodu powyższe oprogramowanie pośredniczące powodowało problem z niezdefiniowaniem użytkownika w moim szablonie. Musiałem ponownie dostarczyć obiekt użytkownika do widoku, aby naprawić to w następujący sposób: app.use(function(req,res,next){ res.locals.login = req.isAuthenticated(); res.locals.user = req.user; next(); });
Tebbers
Nawet po pomyślnym uwierzytelnieniu isAuthenticateddaje false w następnym żądaniu. Czy mógłbyś pomóc odpowiedzieć na to pytanie stackoverflow.com/questions/42842171/…
Suhail Gupta
3

Nie jest to wyraźnie udokumentowane, ale nie jest to isAuthenticated()sposób, który jest wkładany reqprzez paszportu .
Może być używany w następujący sposób,

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
źródło
2

Szukałem takiego rozwiązania i trafiłem na tę stronę. Pytanie brzmi, jak sprawdzić status logowania po stronie klienta.

Po zalogowaniu ukrywam przycisk Zaloguj i pokazuję przycisk wylogowania. Po odświeżeniu strony ponownie widzę przycisk logowania zamiast przycisku wylogowania. Jedynym rozwiązaniem jest zapisanie elementu w sessionStorage, jeśli używasz sesji (i localStorage, jeśli używasz JWT). Usuń ten element po wylogowaniu. Następnie przy każdym ładowaniu strony sprawdź ten element sessionStorage i wykonaj odpowiednie czynności.

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
źródło
2

użyj poniższego kodu wewnątrz app.get () lub router.get ()

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

      }
  else{
   res.redirect('/users/login');//your particular login routes
     }
});
Pankaj
źródło
0

Dobre pytanie, miałem pewne problemy podczas próby zaimplementowania czegoś takiego, gdy pojawia się nieuwierzytelnione żądanie, kierownica pomija blok if, jeśli zmienna res.locals zwraca fałszywą wartość. Aby rozwiązać ten problem, musisz skonfigurować oprogramowanie pośredniczące w pliku app.js, aby req.user był dostępny globalnie w Twojej aplikacji.

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

});

W pliku nagłówkowym możesz sprawdzić, czy użytkownik jest uwierzytelniony i wyświetlić zgodnie z zawartością, taką jak ta.

                {{#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
źródło