45
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Nest.jsでCORSを許可する

Last updated at Posted at 2018-12-25

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

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/

45
25
2

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
45
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?