ユーザーがpassport.jsでログインしているかどうかを知る方法は?


104

passport.js情報とサンプルを2日間読んでいますが、その後、認証のすべてのプロセスを実行したかどうかはわかりません。

たとえば、ログインボタンまたはログアウトボタンのあるナビゲーションバーがある場合、ログインしているかどうかはどうすればわかりますか。以下のコードのような変数はありますか?

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

回答:


210

ユーザーがログインしpassport.jsているuser場合、reqはすべてのリクエストに対してオブジェクトを作成しますexpress.js。これにより、任意のミドルウェアに存在するかどうかを確認できます。

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

express.jsそのための簡単なミドルウェアを作成できます。これにより、ユーザーがログインしているかどうかがチェックされ、ログインしていない場合は/loginページにリダイレクトされます。

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

そしてそれを使う:

app.get('/orders', loggedIn, function(req, res, next) {
    // req.user - will exist
    // load user orders and render them
});

グローバルですか?ログイン後にすべてのプロジェクトでアクセスできますか?
RMontes13 2013

3
グローバルではなく、リクエストオブジェクトに対してのみです。
超新星

1
express.jsとpassport.jsを使用したWeb開発の98.8%では、リクエスト(app.get、app.postなど)を処理するため、それ以外でのpassport.jsの使用について話しても意味がありません。はいapp.getapp.postなどの高速ルートミドルウェアハンドラ内にのみ存在します。別の機能が必要な場合は、質問の詳細と達成しようとしていることを説明する必要があります。
moka 2013

2
「router.get( '/'、my_controller.index)」のように、router.get()に認証をチェックするミドルウェアを提供しない場合、パスポートは参照されず、req.userは常に未定義であること。すべての訪問者がAPIを呼び出せるようにしたいが、だれが要求しているかに応じて応答の内容を調整したいので、これはイライラします。
ローレンスI.サイドン2014年

2
これがどのように悪用されないのか誰かが説明できますか?このチェックは、リクエストのユーザーオブジェクトであるかどうかを確認するだけです。セッション検証はどこにありますか?
rambossa

46

コードサンプルが次のようなミドルウェアを作成できることを示しているように、テンプレートで使用したい場合:

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

パスポートをセットアップした後、どこかにそのコードを配置します。

そして、それをテンプレートで使用します(swigの例)

{% if login %}
<button>logout</button>
{% else %} 
<button>login</button>
{% endif %}

なんらかの理由で、上記のミドルウェアで、テンプレートでユーザーが定義されていないという問題が発生しました。私はそれがとても好きで修正するためにビューにユーザーオブジェクトを再供給しなければならなかった: app.use(function(req,res,next){ res.locals.login = req.isAuthenticated(); res.locals.user = req.user; next(); });
Tebbers

認証が成功した後でもisAuthenticated、次のリクエストでfalseを返します。あなたはこの質問に答える助けてもらえstackoverflow.com/questions/42842171/...
Suhailグプタ

3

明示的に文書化されていませんが、passportによってisAuthenticated()挿入さreqれるメソッドがあります。 次のように使用できます。

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'))

2

私はそのような解決策を探していて、このページに出くわしました。質問は、クライアント側でログインステータスを確認する方法です。

ログインした後、「ログイン」ボタンを非表示にし、「ログアウト」ボタンを表示します。ページの更新時に、ログアウトボタンの代わりにログインボタンが再び表示されます。唯一の解決策は、セッションを使用している場合はsessionStorage(およびJWTを使用している場合はlocalStorage)にアイテムを保存することです。ログアウト時に削除してください。次に、すべてのページの読み込みで、このsessionStorageアイテムを確認し、それに応じて行います。

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'); };
}; 

2

app.get()またはrouter.get()内で以下のコードを使用します

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

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

0

良い質問です。このようなものを実装しようとしたときにいくつかの問題がありました。認証されていないリクエストがあると、res.locals変数が偽の値を返す場合、ハンドルバーがifブロックをスキップします。この問題を解決するには、ミドルウェアをapp.jsファイルに設定して、req.userをアプリでグローバルに使用できるようにする必要があります。

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

});

ヘッダーファイルでは、認証されたユーザーに対してこのチェックを実行し、それに応じてコンテンツを表示できます。

                {{#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}} 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.