LoginSignup
2
2

Access-Control-Allow-Credentials: trueにしないとsessionをCookieに保存できない

Posted at

卒研でWebアプリを開発しており、ログインセッションの実現をしようとしていたところ思いのほか躓いたので記事書くことにしました。

ここではExpressでのsession構築、Redis構築の話は一切行いません。予めご了承ください。
説明は致しませんが、この記事の最下部にて私が参考にしたURLを貼っております。

Cookieがセットされない…

express-sessionというライブラリを使って、Redisにセッション情報を保存しつつログインセッションを実現しようと思い環境構築を行っていました。
いろんな方のブログや公式リファレンスを参考にして、いざやってみるとなぜかブラウザにCookieがセットされない。
ブラウザの検証ツールで確認してみると、通信は正常に行われており、Set-Cookieもレスポンスヘッダーに存在し、ますます路頭に迷う羽目となっておりました。

ざっくり環境

  • Front: SvelteKit & Svelte
    • Library: Axios
  • Back: Node.js(Express)
  • DBMS: Redis
  • Middle: Docker・Docker Compose・Ubuntu(limaというアプリで仮装環境構築)

結論

api/index.js
import axios from 'axios';

const axiosInstance = axios.create({
  baseURL: 'http://localhost:3000',
  headers: {
    'Content-Type': 'application/json',
    'X-Request_With': 'XMLHttpRequest',
  },
  responseType: 'json',
  withCredentials: true, // AjaxでCookieを使用するのに必須
});

フロント側では、Ajaxを行う際にAxiosを使用。
今までwithCredentialsというオプションはつけていなかったのですが、AjaxでCookieを使用する場合は必要みたいですので、付け加えます。
...が、フロント側でwithCredentialsをつけても、サーバー側で許可してない場合、CORS Policy違反となりフロントとサーバーのやりとりが拒絶されます。
なので、サーバー側でCORS Policyの設定を行います

src/index.ts
// 上記の方で色々importやインスタンス化を行っているが結構あるため省略
app.set('trust proxy', 1);
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(
// express-sessionというライブラリでsessionを実現
// そのためのconfig
  expressSession({
    secret: 's3Cur3',
    name: 'session',
    resave: false,
    saveUninitialized: true,
    store,
  })
);
// CORS系設定
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', ['http://localhost:5000']);
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type, x-request_with, XMLHttpRequest')
  // ↓がwithCredentialsを許可する設定
  res.header('Access-Control-Allow-Credentials', 'true')
  next();
});

上記では、withCredentialsについて、「AjaxでCookieを使用する場合は必要」と記述したのですが、正確には以下のようです

Access-Control-Allow-Credentials レスポンスヘッダーは、リクエストの資格情報モード (Request.credentials) が include である場合に、レスポンスをフロントエンドの JavaScript コードに公開するかどうかをブラウザーに指示します。
証明書の資格情報モード (Request.credentials) が include である場合、レスポンスがフロントエンドの JavaScript コードに公開されるのは Access-Control-Allow-Credentials の値が true である場合のみです。
資格情報は Cookie、認証ヘッダー、または TLS クライアント証明書です。

Access-Control-Allow-Credentials - HTTP - MDN Web Docs

AjaxはJavaScriptを用いて非同期的に通信を行うもので、その際にCookie、認証ヘッダー、TLSクライアント証明書を使用するにはwithCredentialsのCORSをtrueにする必要があるみたいです。

参考先

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2