やりたいこと
サーバー側からのHttpレスポンスヘッダーに付与されているset-cookieヘッダーのドメイン属性をlocalhostに変換してブラウザ上にcookieを保存する!!
利用するライブラリとかツールとか
全体像イメージ
ブラウザからサーバーに対しての問い合わせ
client(chrome)→proxy(localhsot:8000)→ngrok(中身的にはlocalhost:6000)
お問い合わせに対する返信に、proxyがset-cookieヘッダーのドメインをlocalhostに書き換える。
ディレクトリ
ディレクトリ構成は以下の通り。
tree -I node_modules
.
├── package-lock.json
├── package.json
├── proxy.js
├── public
│ └── index.html
└── server.js
client
ブラウザで開くページ。画面リロードで、proxyの http://localhost:8000/api
にリクエストする。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>クライアント</title>
</head>
<body>
<script>
fetch("http://localhost:8000/api", {
credentials: "include",
})
.then((response) => response.json())
.then((data) => console.log(data));
</script>
</body>
</html>
proxy
クライアントのindex.html
をホスティングしながら、サーバーからくるHttpのレスポンスのset-cookieのドメイン属性を、localhostに書き換えしてる。書き換えは、 http-proxy-middleware
を利用している。createProxyMiddleware()
の引数で渡すoptions()
内で、set-cookieのドメイン属性をどうするか指定している。
クライアントからは、http://localhost:8000/api
にきたHttpリクエストをngrokのhttpsにプロキシしてる。
const path = require("path");
const express = require("express");
const { createProxyMiddleware } = require("http-proxy-middleware");
const app = express();
const options = function (target) {
return {
target,
changeOrigin: true,
cookieDomainRewrite: "localhost",
onError: function onError(err, req, res) {
console.error(err);
},
};
};
// ここのoptionsの引数に後述するngrokのコマンドで出力されたhttps~~~を記入してください
const proxy = createProxyMiddleware(
options("https://84ea-124-195-153-220.ngrok.io")
);
app.use(["/api"], proxy);
app.use(
"/client-view",
express.static(path.join(__dirname, "public/index.html"))
);
const PORT = 8000;
app.listen(PORT, () => {
console.log(`\app listening at http://localhost:${PORT}\n`);
});
server.js
/api
にきたリクエストに対して、set-cookieヘッダーを付与するレスポンスを返してる。
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors({ origin: true, credentials: true }));
app.get("/api", (req, res) => {
res.cookie("cookie-name", "cookie-value", {
path: "/",
maxAge: 60000,
secure: true,
HttpOnly: true,
});
res.json({});
});
app.listen(6000, () => console.log("Example app listening on port 6000!"));
起動方法
クライアント側の起動と、プロキシの起動。
node proxy.js
サーバー側の起動。
node server.js
serverが6000番portで立ち上がるのでngrokでlocalhostをhttpsに変換。
ngrok http 6000
テスト
http://localhost:8000/client-view
にアクセス!
DevToolsを開いてみる
結果
ばっちし。
最後に
cookieをどうやったらブラウザに保存できるか考えこのような形に。まとめてみるとこんな感じで結構簡単そうにみえますが、辿り着くまでが中々難しい。ngrokならびに便利なツールやライブラリに感謝を。