Skip to content

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

@CelularPrism

Description

@CelularPrism

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_PUBLIC_IP)' 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_PUBLIC_IP)' 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)

  • Chrome 121.0.6167.87 (Official Build) (64-bit) on Windows 10.
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;
		}
	}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions