私の質問はこれに似ています 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
}
アプリのセッション状態を設定しましたか?このようなものが必要です...
app.use(session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
私の問題は、クライアント側でフェッチを使用するときにクッキーを送信するように指定していませんでした。リクエストに認証情報: 'include'フィールドを含めた後に機能しました。
fetch('/api/foo', {credentials: 'include'})
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);
お役に立てれば
以前、私はこれらのコードを持っています(動作しませんでした):
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')));
そして今、それは動作します。
ええ、@ Martinのようなセッションを有効にします。ただし、Express 4. *バージョンを使用している場合、セッションのようなミドルウェアはバンドルされていないため、個別にインストールする必要があります。
;
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'}))
詳細については、 エクスプレスセッションドキュメント を確認してください。
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
}))
ルートに追加してみてください:{session: true}
app.get('/auto-login', passport.authenticate('cross', {session: true}))
エクスプレス4を使用してもまったく同じ問題が発生し、オンラインで見つけることができるすべてのことを試した後、「cookie-session」を追加することでようやく機能するようになりました。
var cookieSession = require('cookie-session');
app.use(cookieSession({
keys: ['key1', 'key2']
}));
私はクッキーとコルについてでした。サーバーに次のコードを追加して解決しました。
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();
}};
クライアント側でhttpリクエストを使用するときは、必ず資格情報を添付してください。 Angular2では、オプション引数{withCredentials:true}を追加する必要があります。この後、再度リセットするまで、同じreq.sessionIDがあります。
this._http.get("endpoint/something", { withCredentials: true })
エクスプレスセッションのセットアップが完了したら、req.userが生成されるときのdeserialize関数で、パスポートのシリアル化と逆シリアル化が行われていることを確認します。別のstackoverflow質問からの説明 here を参照してください。
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
ミドルウェアスタックが不明確な場合、セッションミドルウェアsomewhereがあると仮定すると、リダイレクトの前にセッションを保存できます。
if (req.user) {
req.session.save(function (err) {
if (err) {
// ... panic!
}
res.redirect("/user/" + req.user._id);
});
return;
}
私の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
}
})
);
passport.authenticate
あなたは付け加えられます session: true
問題を解決するには:
app.post("/login", passport.authenticate('local', {
'failureRedirect': '/login',
'session': true
}), (req, res)=>{ res.redirect("/"); });
サーバーは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();
}
});
ユーザーを認証すると、リクエスト値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' }
私のものはこれらすべてとは異なっていました。私は以前localhostでWordpressサイトを開発してから、別のNode/Reactプロジェクトに切り替えました。
WordpressサイトからのCookieはまだ存在しており、両方のプロジェクトがローカルホストで実行されているため送信されています。これが問題の原因でした。
LocalhostのCookieをクリアする必要があり、それが機能しました。
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にアクセスする場合は、ルートを追加しないでください。
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());
まったく同じ問題がありました。私にとって、解決策は「エクスプレスセッション」の代わりに「クライアントセッション」を使用することでした。
動作しないコード:
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,
}));