gaeにデプロイされているNest.jsプロジェクトで、レスポンスをエッジサーバーにキャッシュさせたい。
tl;dr
- いい感じのHeader設定すればキャッシュできそう
- csurf使ってると
set-cookie
が邪魔 - interceptorでresponseのheaderから
set-cookie
ヘッダーを削除
GAEでキャッシュを効かせるための方法
以下の記事を見るにCache-Control
ヘッダーを設定してやればいいっぽい
nestjsでの実現方法
Cache-Control
を設定するだけであれば@Header
デコレータを使えばできそう
csurfを使ってるとできなかった
csrfの対策でcsurfというmiddlewareを使用していて、これがset-cookie
を返していて上記のgcpの記事を見ているとキャッシュできないっぽかった。
csurfのソースコードを見てもset-cookie
を回避する方法がなかったので、なんとかキャッシュできないかとNest.jsのドキュメントを眺めているとinterceptorで特定のエンドポイントだけset-cookie
を削除する方法を思いついた。
やってみた
csurfの導入はしている前提でNest.jsのプロジェクトを作成したらデフォルトでできるcontrollerで実験してみる。
interceptorを定義
// interceptor.ts import {CallHandler, ExecutionContext, NestInterceptor} from '@nestjs/common' import {Observable} from 'rxjs' export class RemoveSetCookieInterceptor implements NestInterceptor { intercept( context: ExecutionContext, next: CallHandler<any> ): Observable<any> | Promise<Observable<any>> { const res = context.switchToHttp().getResponse() res.removeHeader('set-cookie') return next.handle() } }
Nest.jsのinterceptorのドキュメントを参考にcontrollerに@UseInterceptor
のデコレーターを設定
# before $ curl -I 'http://localhost:3000/' HTTP/1.1 200 OK X-Powered-By: Express Access-Control-Allow-Origin: * Vary: Origin Access-Control-Allow-Credentials: true set-cookie: _csrf=3vAswtvct-xiqGdjiPYXpz6v; Max-Age=3600000; Path=/; HttpOnly Content-Type: text/html; charset=utf-8 Content-Length: 12 ETag: W/"c-Lve95gjOVATpfV8EL5X4nxwjKHE" Date: Mon, 14 Dec 2020 09:33:57 GMT Connection: keep-alive Keep-Alive: timeout=5 # after curl -I 'http://localhost:3000/' HTTP/1.1 200 OK X-Powered-By: Express Access-Control-Allow-Origin: * Vary: Origin Access-Control-Allow-Credentials: true Content-Type: text/html; charset=utf-8 Content-Length: 12 ETag: W/"c-Lve95gjOVATpfV8EL5X4nxwjKHE" Date: Mon, 14 Dec 2020 09:37:13 GMT Connection: keep-alive Keep-Alive: timeout=5
これで特定のheaderを削除できるようになったので乱用はできないけどキャッシュはできそう。