OpenVidu / openvidu

OpenVidu Platform main repository
https://openvidu.io
Apache License 2.0
1.86k stars 464 forks source link

OpenVidu Docker using Access-Control-Allow-Origin "*" header #827

Open CelularPrism opened 6 months ago

CelularPrism commented 6 months ago

Describe the bug I have deployed OpenVidu Docker according to the documentation(https://docs.openvidu.io/en/stable/deployment/ce/on-premises/), configured custom nginx and I need to access the server on another site. A CORS error occurs during the request

_Access to XMLHttpRequest at '(DOMAIN_OR_PUBLICIP)' from origin 'http://localhost:4200/' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

Expected behavior When I added the add_header 'Access-Control-Allow-Origin' "localhost:4200" line to custom-nginx, the following error is displayed when requesting

_openvidu:1 Access to XMLHttpRequest at '(DOMAIN_OR_PUBLICIP)' from origin 'http://localhost:4200/' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header contains multiple values '*, http://localhost:4200/', but only one is allowed.

I also thought that the problem might be in .env, I tried to correct the parameters ALLOWED_ACCESS_TO_DASHBOARD and ALLOWED_ACCESS_TO_RESTAPI, but the error is the same

OpenVidu tutorial where to replicate the error

  1. Clone repository curl https://s3-eu-west-1.amazonaws.com/aws.openvidu.io/install_openvidu_latest.sh | bash
  2. Run OpenVidu Server like this ./openvidu start
  3. Enter on the page, send request (DOMAIN_OR_PUBLIC_IP)/call/config
  4. See error

Client device info (if applicable)

import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { RecordingInfo } from 'openvidu-angular';
import { lastValueFrom } from 'rxjs';

interface SessionResponse {
    cameraToken: string;
    screenToken: string;
    recordingEnabled: boolean;
    isRecordingActive: boolean;
    recordings?: RecordingInfo[];
    broadcastingEnabled: boolean;
    isBroadcastingActive: boolean;
}
@Injectable({
    providedIn: 'root'
})
export class RestService {
    private baseHref: string;

    constructor(private http: HttpClient) {
        // this.baseHref = '/' + (!!window.location.pathname.split('/')[1] ? window.location.pathname.split('/')[1] + '/' : '');
        this.baseHref = '(DOMAIN_OR_PUBLIC_IP)';
    }

    async login(username: string, password: string): Promise<{ logged: boolean }> {
        return this.postRequest('auth/login', { username, password });
    }

    async getConfig() {
        return await this.getRequest('call/config');
    }

    async getTokens(sessionId: string, nickname?: string): Promise<SessionResponse> {
        return this.postRequest('sessions', { sessionId, nickname });
    }
    adminLogin(password: string): Promise<any[]> {
        return this.postRequest('auth/admin/login', { password });
    }
    adminLogout(): Promise<void> {
        return this.postRequest('auth/admin/logout', {});
    }

    getRecordings() {
        return this.getRequest(`recordings/`);
    }

    startRecording(sessionId: string) {
        return this.postRequest('recordings/start', { sessionId });
    }

    stopRecording(sessionId: string) {
        return this.postRequest('recordings/stop', { sessionId });
    }

    deleteRecording(recordingId: string): Promise<RecordingInfo[]> {
        return this.deleteRequest(`recordings/delete/${recordingId}`);
    }

    async startBroadcasting(broadcastUrl: string) {
        const options = {
            headers: new HttpHeaders({
                'Content-Type': 'application/json'
            })
        };
        return this.postRequest('broadcasts/start', { broadcastUrl }, options);
    }

    stopBroadcasting() {
        return this.deleteRequest('broadcasts/stop');
    }

    private postRequest(path: string, body: any, options?: any): Promise<any> {
        try {
            return lastValueFrom(this.http.post<any>(this.baseHref + path, body, options));
        } catch (error: any) {
            if (error.status === 404) {
                throw { status: error.status, message: 'Cannot connect with backend. ' + error.url + ' not found' };
            }
            throw error;
        }
    }

    private getRequest(path: string, responseType?: string): any {
        try {
            const options: any = {};
            if (responseType) {
                options['responseType'] = responseType;
            }
            return lastValueFrom(this.http.get(`${this.baseHref}${path}`, options));
        } catch (error: any) {
            if (error.status === 404) {
                throw { status: error.status, message: 'Cannot connect with backend. ' + error.url + ' not found' };
            }
            throw error;
        }
    }

    private deleteRequest(path: string) {
        try {
            return lastValueFrom(this.http.delete<any>(`${this.baseHref}${path}`));
        } catch (error: any) {
            console.log(error);
            if (error.status === 404) {
                throw { status: error.status, message: 'Cannot connect with backend. ' + error.url + ' not found' };
            }
            throw error;
        }
    }
}