NestJS - 如何为响应设置“Access-Control-Allow-Origin”标头

问题描述

我正在尝试在 nestJS 中设置响应标头,但不断收到以下错误

跨源请求被阻止:同源策略不允许读取位于 https://companyName.okta.com/app/companyName_imentorlocalhost_1/exk1hp5ht4vrEzqGg0h8/sso/saml?SAMLRequest=nVPLct.. 的远程资源。 (原因:缺少 CORS 标头“Access-Control-Allow-Origin”)。

我尝试在控制器中设置标题,但没有用:

auth.controller

@UseGuards(SamlAuthGuard)
@Header('Access-Control-Allow-Origin','*')
@Get('Box-utility-service/auth/login')
login(@Request() req): any {}

@UseGuards(SamlAuthGuard)
@Header('Access-Control-Allow-Origin','*')
@Post('imentor-service/login/callback')
oktaCallback (@Request() req,@Response() res: Response): any {
    return this.authService.login(req);
}

还尝试在拦截器中设置标头。也没有用:

header.interceptor.ts

@Injectable()
export class HeaderInterceptor implements nestInterceptor {
  intercept(context: ExecutionContext,next: CallHandler): Observable<any> {
    return next.handle().pipe(
      tap(() => {
        const res = context.switchToHttp().getResponse();

        res.setHeader('Access-Control-Allow-Origin','*');
      })
    )
  }
}

这是我的 main.ts,我在其中启用了 CORS:

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

  app.use(
    session({
      secret: 'my-secret',resave: false,saveUninitialized: false
    }),);

  app.enableCors({
    allowedHeaders: [ 'Accept','Accept-Version','Content-Type','Api-Version','Origin','X-Requested-With','Authorization' ],origin: [ 'https://companyName.okta.com','http://localhost:4200','http://localhost' ],credentials: true,exposedHeaders: [ 'API-Token-Expiry' ]
  });

  app.useGlobalInterceptors(new HeaderInterceptor());

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

这是我的 saml-strategy.ts 文件,我将 Passport 策略定义为 SAML:

import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { AuthService } from './auth.service';
const nconf = require('nconf');
import { get } from 'lodash';
const SamlStrategy = require('passport-saml').Strategy;

import { UseRSService } from '../users/users.service';

@Injectable()
export class Saml2Strategy extends PassportStrategy(SamlStrategy,'saml') {
  users = [];

  constructor(
    private authService: AuthService,private useRSService: UseRSService
  ) {
    super({
      issuer: nconf.get('saml:issuer'),path: nconf.get('saml:path'),entryPoint: nconf.get('saml:entryPoint'),cert: nconf.get('saml:cert')
    });
  }

  async validate(payload: any) {
    const oeid = payload.nameID;
    let user;

    if (oeid) {
      try {
        let userADData = await this.authService.validateUser(oeid);
        userADData = get(userADData,'data.data[0]');

        if (userADData) {
          user = await this.useRSService.findOrCreate(userADData);
        }

        return user;
      } catch (err) {
        return err;
      }
    }
  }
}

知道发生了什么吗?谢谢。

解决方法

原来是我处理 OKTA 登录工作流程的方式有问题。我正在重定向 XHR 请求(OKTA 不喜欢它,因为它缺少执行此操作所需的标头),并且收到错误代码。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...