web-dev-qa-db-ja.com

Node + Express + Passport:req.user Undefined

私の質問はこれに似ています one ですが、彼の解決策に対する洞察はありませんでした。

Instagramを使用して認証するためにPassportを使用しています。認証に成功すると、ユーザーは「/」にリダイレクトされます。この時点で、リクエストにはユーザーオブジェクトがあります(別名:動作しています)。ただし、リダイレクトすると、req.userは未定義になります。 : '(

奇妙な部分は、各リクエストでpassport.deserializeUserが呼び出されることです。ユーザーオブジェクトは正常に取得されていますが、ミドルウェアロードのどこかで、req.userは設定されていません(または設定解除されています)。

// on successful auth, goto "/" 
app.get('/', function(req, res) {
    // if the request has the user object, go to the user page
    if (req.user) {
        res.redirect("/user/" + req.user._id);
    }

    res.render("index");
}

app.get('/user/:uid', function(req, res) {
    console.log(req.user) // undefined
}
61
gojohnnygo

アプリのセッション状態を設定しましたか?このようなものが必要です...

app.use(session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
38
Martin

私の問題は、クライアント側でフェッチを使用するときにクッキーを送信するように指定していませんでした。リクエストに認証情報: 'include'フィールドを含めた後に機能しました。

fetch('/api/foo', {credentials: 'include'})
48
Jon Rodness

Nodeが初めてですが、それはミドルウェアの問題でした。bodyParserを追加し、修正するために再配置しました。

壊れたコード:

app.use(express.cookieParser('secret'));
app.use(express.cookieSession());
app.use(express.session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public'))); 

作業コード:

app.use(express.static(path.join(__dirname, 'public')));
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);

お役に立てれば

15
leylandjacob

以前、私はこれらのコードを持っています(動作しませんでした):

app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser('abcdefg'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(session({
    secret: 'abcdefg',
    resave: true,
    saveUninitialized: false,
    cookie: { secure: true } // this line
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));

次に、セッション初期化子からCookieオプションを削除します。

app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser('abcdefg'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(session({
    secret: 'abcdefg',
    resave: true,
    saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(require('stylus').middleware(path.join(__dirname, 'public')));

そして今、それは動作します。

8
user3323765

ええ、@ Martinのようなセッションを有効にします。ただし、Express 4. *バージョンを使用している場合、セッションのようなミドルウェアはバンドルされていないため、個別にインストールする必要があります。

  1. Package.jsonに "express-session": "1.4.0" を追加します
  2. npmインストール
  3. これを使って

;

var express = require('express');
var cookieParser = require('cookie-parser')
var session = require('express-session')
var app = express()
app.use(cookieParser()) // required before session.
app.use(session({secret: 'keyboard cat'}))

詳細については、 エクスプレスセッションドキュメント を確認してください。

4
Adrian Enriquez

Expressセッションのドキュメントから次のコードをコピー&ペーストするだけで同じ問題が発生しますが、ドキュメントを完全に読むことはできません。

app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: true }
}))

ドキュメントでは、次のように言及しました。

ただし、https対応のWebサイトが必要です。つまり、安全なCookieにはHTTPSが必要です。セキュアが設定されていて、HTTP経由でサイトにアクセスする場合、Cookieは設定されません。

hTTP接続している場合は、セキュアオプションを削除すると、以下のコードが機能するはずです。

app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  //cookie: { secure: true } remove this line for HTTP connection
}))
4
ufxmeng

ルートに追加してみてください:{session: true}

app.get('/auto-login', passport.authenticate('cross', {session: true}))
3
Strawberry

エクスプレス4を使用してもまったく同じ問題が発生し、オンラインで見つけることができるすべてのことを試した後、「cookie-session」を追加することでようやく機能するようになりました。

var cookieSession = require('cookie-session');

app.use(cookieSession({
  keys: ['key1', 'key2']
}));
3
ergusto

私はクッキーとコルについてでした。サーバーに次のコードを追加して解決しました。

allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:3000'); // your website
res.header('Access-Control-Allow-Credentials', 'true');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
if ('OPTIONS' === req.method) {
    res.send(200);
} else {
    next();
}};
1
MmtBkn

クライアント側でhttpリクエストを使用するときは、必ず資格情報を添付してください。 Angular2では、オプション引数{withCredentials:true}を追加する必要があります。この後、再度リセットするまで、同じreq.sessionIDがあります。

this._http.get("endpoint/something", { withCredentials: true })
1
Honzik

エクスプレスセッションのセットアップが完了したら、req.userが生成されるときのdeserialize関数で、パスポートのシリアル化と逆シリアル化が行われていることを確認します。別のstackoverflow質問からの説明 here を参照してください。

passport.serializeUser(function(user, done) {
 done(null, user);
});


passport.deserializeUser(function(user, done) {
 done(null, user);
});
1
Aric Sangchat

ミドルウェアスタックが不明確な場合、セッションミドルウェアsomewhereがあると仮定すると、リダイレクトの前にセッションを保存できます。

if (req.user) {
    req.session.save(function (err) {
        if (err) {
            // ... panic!
        }
        res.redirect("/user/" + req.user._id);
    });
    return;
}
0
exclsr

私の2セント:動作しないコード:

server.use(
session({
  secret: "secretsssss",
  rolling: false,
  resave: false,
  saveUninitialized: false,
  cookie: {
    sameSite: true, //this line
    maxAge: 60 * 60 * 1000
  }
})
);

作業コード:

server.use(
session({
  secret: "secretsssss",
  rolling: false,
  resave: false,
  saveUninitialized: false,
  cookie: {
    sameSite: false, // i think this is default to false
    maxAge: 60 * 60 * 1000
  }
})
);
0
Ruizhen Mai

passport.authenticate あなたは付け加えられます session: true問題を解決するには:

app.post("/login", passport.authenticate('local', {
    'failureRedirect': '/login',
    'session': true
}), (req, res)=>{ res.redirect("/"); });
0
Mahesh

サーバーはSetCookieヘッダーを送信し、次にブラウザーがそれを保存するためにハンドルし、CookieがCookie HTTPヘッダー内の同じサーバーに行われたリクエストとともに送信されます。

クライアントでwithCredentials:trueを設定する必要がありました。 (axios.js)

const config = {
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json',
  },
};

axios.put(url, { page: '123' }, config)
  .then(res => console.log('axios', res))
  .catch(err => console.log('axios', err));

その後、CORSの問題が発生します。

そこで、これをエクスプレスサーバーに追加しました。

app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Credentials', true);
  res.header('Access-Control-Allow-Origin', req.headers.Origin);
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
  if ('OPTIONS' == req.method) {
    res.send(200);
  } else {
      next();
  }
});
0
Sunny Sultan

ユーザーを認証すると、リクエスト値req.userは塗りつぶされています。がユーザーを識別してその値を埋めるかどうかを知るために、Cookieが使用されます。私のように、セキュアCookieを使用してセッションを設定すると、CookieはHTTPSを介してのみ使用可能になります。これは、たとえばローカル開発サーバーの標準構成ではありません。 HTTPでCookieを機能させるには、cookie: { secure: true }およびreq.user値は適切に構成されます。

this.app.use(session({
    resave: true,
    saveUninitialized: true,
    secret: process.env.SESSION_SECRET || "a secret",
    // cookie: { secure: true },
}));

合理的に、本番環境でのみHTTPSを介したCookieが必要な場合は、次のようなことができます。

cookie: { secure: process.env.ENV === 'PRODUCTION' }
0
Alain1405

私のものはこれらすべてとは異なっていました。私は以前localhostでWordpressサイトを開発してから、別のNode/Reactプロジェクトに切り替えました。

WordpressサイトからのCookieはまだ存在しており、両方のプロジェクトがローカルホストで実行されているため送信されています。これが問題の原因でした。

LocalhostのCookieをクリアする必要があり、それが機能しました。

0
Breakpoint25

Req.isAuthenticated()とreq.userの両方で同じ問題が発生しました。ここで解決しました。

  • deserialize()内のfindById()メソッドでfindOne()をfind()に置き換えることでreq.isAuthenticated()を解決し、認証済みのreqを保存できました。それ以外は何も返しませんでした。

  • req.userは順序を調整することで解決され、最初のエクスプレスセッションが保存され、次にパスポートが初期化され、次のセッションがpassport.session()に保存され、その後、passport.session()にセッションを保存した後、req.userにアクセスできます

_app.use(session(...));
app.use(passport.initialize());
app.use(passport.session());
// Now we can access req.user so after we will call req.user, if we write it above these, it will always return underfined
app.use(function(req, res, next){
  res.locals.user = req.user || null
  next();
})_

passport.session()の後にreq.userにアクセスする場合は、ルートを追加しないでください。

0

CookieParserにsecretKeyを挿入しようとしましたか?

var passport = require('passport');
var expressSession = require('express-session');

app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser('mySecretKey'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(expressSession({
secret: 'mySecretKey',
  resave: false,
  saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
0
Marco Mantovani

まったく同じ問題がありました。私にとって、解決策は「エクスプレスセッション」の代わりに「クライアントセッション」を使用することでした。

動作しないコード:

var session = require('express-session');

app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(session({
    secret: 'random string',
    resave: true,
    saveUninitialized: true,
    cookie: { secure: true }
}));

作業コード:

var session = require('client-sessions');

        app.use(bodyParser.urlencoded({ extended: false }));
        app.use(express.static(path.join(__dirname, 'public')));
        app.use(cookieParser());
        app.use(bodyParser.json());
        app.use(session({
        cookieName: 'session',
        secret: 'random string',
        duration: 30 * 60 * 1000,
        activeDuration: 5 * 60 * 1000,
    }));
0
Luis