Express経由でのCookieの設定に問題があります。 _Este.js dev stack
_を使用していますが、API認証_/login
_ルートでCookieを設定しようとしています。 _/api/v1/auth/login
_ ルートで使用するコードは次のとおりです
_res.cookie('token', jwt.token, {expires: new Date(Date.now() + 9999999)});
res.status(200).send({user, token: jwt.token});
_
_src/server/main.js
_に_cookie-parser
_を最初のミドルウェアとして登録しました
_app.use(cookieParser());
_
_/api/v1/auth/login
_ルートの応答ヘッダーには
_Set-Cookie:token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJ..
_
が、Cookieはブラウザに保存されません(_document.cookie
_は空です、develepoersツールの_Resources - Cookies
_タブも空です): (
EDIT:_/api/v1/auth/login
_でこれを呼び出すと(_res.send
_または_res.json
_を呼び出さずに)
res.cookie('token', jwt.token, {expires: new Date(Date.now() + 9999999), httpOnly: false});
next();
その後、Cookieが設定されますそして、応答ヘッダーは_X-Powered-By:Este.js
_を設定します...これは expresでesteMiddleware
を設定しますフロントエンドレンダリングパーツ 。
_res.send
_を使用する場合
_res.cookie('token', jwt.token, {expires: new Date(Date.now() + 9999999), httpOnly: false}).send({user, token: jwt.token});`
next();
_
send
メソッドが使用されているため、エラー_Can't set headers after they are sent.
_が表示され、フロントエンドレンダーがこのエラーをスローします。
しかし、APIからデータを送信する必要があるので、これにどのように対処できますか?
助けてもらえますか?ありがとう!
同じ問題がありました。サーバーの応答には、Cookieが設定されています。
Set-Cookie:my_cookie=HelloWorld; Path=/; Expires=Wed, 15 Mar 2017 15:59:59 GMT
しかし、クッキーはブラウザによって保存されませんでした。
これは私がそれを解決した方法です。
クライアント側のコードでfetch
を使用しています。 fetch
オプションでcredentials: 'include'
を指定しない場合、Cookieはサーバーに送信されず、ブラウザーによって保存されませんが、サーバーの応答はCookieを設定します。
例:
var headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
return fetch('/your/server_endpoint', {
method: 'POST',
mode: 'same-Origin',
redirect: 'follow',
credentials: 'include', // Don't forget to specify this if you need cookies
headers: headers,
body: JSON.stringify({
first_name: 'John',
last_name: 'Doe'
})
})
それが誰かを助けることを願っています。
私はエクスプレス4とノード7.4と角度で作業しますが、これを助ける同じ問題がありました:
a)サーバー側:app.jsファイルで、すべての応答に次のようなヘッダーを付けます。
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', req.headers.Origin);
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
これはすべてのルーターの前になければなりません。
このヘッダーがたくさん追加されました:
res.header("Access-Control-Allow-Headers","*");
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
しかし、私はそれを必要としません、
b)Cookieを定義するときに、次のようにhttpOnly:falseを追加します。
res.cookie( key, value,{ maxAge: 1000 * 60 * 10, httpOnly: false });
c)クライアント側:ajaxを送信するには、次のように追加する必要があります: "withCredentials:true、" like:
$http({
method: 'POST',
url: 'url,
withCredentials: true,
data : {}
}).then(function(response){
// code
}, function (response) {
// code
});
がんばろう。
いくつかの問題があります:
httpOnly : false
_で明示的に設定されていないCookieは、ブラウザーの_document.cookie
_からnotアクセスできます。 HTTPリクエストとともに送信されます。ブラウザの開発ツールをチェックすると、おそらくCookieが見つかります(Chromeでリソース開発ツールのタブ);next()
は、アプリケーションの他の部分への応答の送信を延期したい場合にのみ使用する必要があります。これは、コードによって判断したものではありません。だから、これはあなたの問題を解決するはずです:
_res.cookie('token', jwt.token, {
expires : new Date(Date.now() + 9999999),
httpOnly : false
});
res.status(200).send({ user, token: jwt.token });
_
サイドノートとして:httpOnly
がデフォルトでtrue
になっている理由があります(悪意のあるXSSスクリプトがセッションCookieなどにアクセスするのを防ぐため)。クライアント側のJSを介してCookieにアクセスできる十分な理由がない場合は、false
に設定しないでください。
Cookieのサイズを再確認してください。
私にとって、Cookieに保存する認証トークンを生成する方法は、その後のログイン試行でCookieのサイズを大きくし、最終的にブラウザが大きすぎるためにCookieを設定しないようにしました。
app.post('/api/user/login',(req,res)=>{
User.findOne({'email':req.body.email},(err,user)=>{
if(!user) res.json({message: 'Auth failed, user not found'})
user.comparePassword(req.body.password,(err,isMatch)=>{
if(err) throw err;
if(!isMatch) return res.status(400).json({
message:'Wrong password'
});
user.generateToken((err,user)=>{
if(err) return res.status(400).send(err);
res.cookie('auth',user.token).send('ok')
})
})
})
});
サーバーは応答を許可しますが、Cookieはブラウザに保存されません
Postman Interceptor Extensionをchromeに追加します。これにより、PostmanはブラウザにCookieを保存し、リクエストの使用を取り戻すことができます。