18
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Nest.jsでCORSを許可する

いくつか方法があるので、それぞれ紹介する。
今回は、クライアントからのリクエストに対して以下のヘッダーが付加されることをゴールとする。

Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept

CORS Middleware

Nest.jsにはMiddlewareという機能があり、リクエスト/レスポンスオブジェクトを任意のタイミングで操作することができます。(ExpressのMiddlewareと同様のイメージ)

まずは、以下のようにNestMiddlewareを実装したMiddlewareを作成します。
ここでは、CorsMiddlewareとしました。

cors.middleware.ts
import { MiddlewareFunction, Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class CorsMiddleware implements NestMiddleware {
  resolve(): MiddlewareFunction {
    return (req: Request, res: Response, next: NextFunction) => {
      res.header('Access-Control-Allow-Origin', '*');
      res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
      next();
    };
  }
}

次に、app.module.tsでMiddlewareを適用します。

app.module.ts
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CorsMiddleware } from './cors.middleware';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer): MiddlewareConsumer | void {
    consumer.apply(CorsMiddleware).forRoutes('*');
  }
}

注意

@MiddlewareというDecoratorがありますが、これは現在Deprecatedになっているので、@Injectable()を使うようにします。

WARNING!!
The @Middleware() decorator is deprecated and will be removed within next major release. Use @Injectable() instead.

app.enableCors()

おそらくこれが一番手軽な方法。
アプリケーションのブートストラップ時にapp.enableCors()を使ってCORSオプションを渡す。

main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  app.enableCors({
    origin: '*',
    allowedHeaders: 'Origin, X-Requested-With, Content-Type, Accept',
  });

  await app.listen(3000);
}
bootstrap();

enableCors()に渡すオプションは次のように定義されているので、上記のoriginとallow headerの他にも細かく設定が可能。

export interface CorsOptions {
    origin?: boolean | string | RegExp | (string | RegExp)[] | CustomOrigin;
    methods?: string | string[];
    allowedHeaders?: string | string[];
    exposedHeaders?: string | string[];
    credentials?: boolean;
    maxAge?: number;
    preflightContinue?: boolean;
    optionsSuccessStatus?: number;
}

app.use()

Nest.jsのHTTP HandlerはExpressのラッパーなので、Expressのインターフェースを間接的に呼び出せる。
次のように、ExpressでMiddlewareを使うときと同様にCORSの有効化ができる。

main.ts
import { NestFactory } from '@nestjs/core';
import { Request, Response, NextFunction } from 'express';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  app.use((req: Request, res: Response, next: NextFunction) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
    next();
  });

  await app.listen(3000);
}
bootstrap();

どれを使えばよいか

ひとまず開発中にCORSを許可したい場合などは、app.enableCors()が一番手軽で良さそう。
よりアプリケーションに近いレイヤーで、CORS関連以外のヘッダー操作も同時に行いたいといった場合には、Middleware化しておいたほうがメンテナンスもしやすくなり、良さそうです。

参考

https://docs.nestjs.com/middleware
https://qiita.com/tomoya_ozawa/items/feca4ffc6217d585b037
https://www.thecodecampus.de/blog/creating-cors-middleware-nest-js/

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
18
Help us understand the problem. What are the problem?