Với vô số mối nguy hiểm đang tiềm ẩn trên internet, việc sử dụng các cơ chế bảo mật như CORS là vô cùng quan trọng và cần thiết. Vậy, Cors là gì? Trong bài viết dưới đây, Vietnix sẽ cung cấp một số thông tin cơ bản về Cors và cách áp dụng Cors một cách hiệu quả trong công việc. Mời bạn cùng tham khảo.
Cors là gì?
Cors là từ viết tắt của Cross-Origin Resource Sharing, được dịch là “Chia sẻ tài nguyên giữa các nguồn gốc khác nhau”. Đây là là một cơ chế bảo mật được tích hợp vào các trình duyệt web nhằm kiểm soát cách các tài nguyên trên trang web có thể được truy cập từ một nguồn gốc khác.
Cụ thể, khi một trang web (trang web A) truy cập tài nguyên từ một trang web khác (trang web B), trình duyệt sẽ thực hiện một cơ chế kiểm tra Cors để xác định xem việc truy cập đó có được phép hay không. Trong đó, yêu cầu Cors sẽ bao gồm các tiêu đề HTTP và nếu trang web B phản hồi là không cho phép truy cập, trình duyệt sẽ chặn yêu cầu đó.
Với Cors, bạn có thể ngăn chặn rủi ro đến từ các cuộc tấn công Cross-Site Request Forgery (CSRF) – một loại tấn công quen thuộc được thực hiện bằng cách lợi dụng quyền truy cập của người dùng trên một trang web khác.
Vai trò của Cors trong phát triển ứng dụng
Cors đóng vai trò vô cùng quan trọng trong việc phát triển các trang web/ứng dụng web. Thông qua cơ chế bảo mật này, các trang web độc lập có thể tương tác và chia sẻ dữ liệu một cách an toàn mà không cần phải dùng đến các phương pháp truyền thống như JSONP hay iFrame.
Trên thực tế, khi có bất kỳ trang web nào muốn truy cập tài nguyên từ trang web khác, trình duyệt web sẽ gửi một yêu cầu HTTP đến trang web đó để lấy tài nguyên. Tuy nhiên, cũng có một vài trường hợp trang web sẽ yêu cầu tài nguyên từ một nguồn khác – hay còn gọi là yêu cầu cross-origin. Các yêu cầu cross-origin thường mang lại nhiều lợi ích trong quá trình phát triển ứng dụng web, nhưng cũng đồng thời tiềm ẩn nhiều rủi ro bảo mật đáng kể.
Lúc này, sự xuất hiện của Cors đã phần nào giải quyết các vấn đề trên. Với cơ chế bảo mật Cors, bạn có thể:
- Ngăn chặn các cuộc tấn công từ xa: Bằng cách hạn chế truy cập tài nguyên từ các trang web không rõ nguồn gốc, Cors có thể ngăn chặn các cuộc tấn công từ xa như CSRF (Cross-site request forgery) hay XSS (Cross-site scripting)…
- Bảo mật dữ liệu quan trọng: Cors bảo vệ trang web khỏi những truy cập trái phép đang cố xâm nhập và lấy cắp dữ liệu nhạy cảm.
- Quản lý phân quyền hiệu quả: Quản trị viên có thể quản lý và kiểm soát các truy cập bằng cách thiết lập quy tắc từ chối hoặc cho phép truy cập tài nguyên từ các nguồn khác nhau trên internet.
Cách thức hoạt động của Cors
Cors hoạt động theo cơ chế sau: Khi một trang web gửi một request từ domain A đến một domain B, trình duyệt sẽ tự động thêm vào một header có tên là Origin. Header Origin là một phần của các chuỗi HTTP header và được dùng để xác định nguồn gốc của một request HTTP. Đặc biệt, không ai có thể thay đổi được header này.
Header Origin có cấu tạo gồm 3 phần:
- Protocol/Scheme: (Http/Https).
- Host: server/domain.
- Port: Cổng, nếu Port có giá trị mặc định là 80 thì sẽ không cần đến thành phần này.
Sau thao tác trên, server sẽ tiến hành kiểm tra xem origin trong request đó có hợp lệ không. Nếu có, server sẽ trả về kết quả là response và đính kèm với header Access-Controll-Allow-Origin. Header này sẽ thông báo cho trình duyệt biết liệu client đó có hợp lệ hay không để trình duyệt tiếp tục tiến hành quá trình request.
Cụ thể, Access-Controll-Allow-Origin sẽ chỉ định các domain được phép truy cập tài nguyên. Trong trường hợp server muốn cho phép truy cập từ mọi domain, header này sẽ sử dụng dấu *
. Tuy nhiên, cách này thường chỉ được áp dụng trong tình huống API của bạn là công khai và ai cũng có thể truy cập, còn lại thường không được khuyến khích vì ẩn chứa khá nhiều rủi ro.
Dưới đây là ví dụ minh hoạ cho 1 request từ https://foo.example:
GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Connection: keep-alive
Origin: https://foo.example
Response:
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
[…XML Data…]
Trong trường hợp kết quả trả về không có header Access-Control-Allow-Origin hoặc giá trị không hợp lệ, trình duyệt web sẽ không thực hiện request và gửi thông báo lỗi.
Hầu hết các header liên quan đến cơ chế bảo mật Cors đều sẽ đi kèm với phần tiền tố Access-Controll. Ngoài Access-Controll-Allow-Origin đã đề cập ở trên, bao gồm:
- Access-Control-Allow-Methods: Liệt kê các phương thức HTTP mà server cho phép client sử dụng (ví dụ: GET, POST, PUT, DELETE).
- Access-Control-Allow_Headers: Chứa danh sách các header mà server đang hỗ trợ, chẳng hạn như
x-authentication-token
. Nếu như trong request mà client gửi không chứa các header có trong danh sách này, server sẽ bỏ qua chúng và ngăn chặn không cho truy cập. - Access-Control-Max-Age: Chỉ định thời gian (tính bằng giây) mà trình duyệt có thể lưu trữ kết quả của một preflight request (một loại request đặc biệt được gửi trước request chính để kiểm tra xem request chính có được phép thực hiện hay không).
Một số truy vấn dùng Cors
Theo quy chuẩn chung, một số truy vấn dưới đây cần phải dùng Cors:
- Truy vấn Ajax: Các truy vấn bất đồng bộ (Ajax) sử dụng XMLHttpRequest hoặc Fetch API để lấy dữ liệu từ một domain khác.
- Tài nguyên nhúng: Các tài nguyên được nhúng vào trang web từ một domain khác, chẳng hạn như hình ảnh, video, iframe hoặc script.
- Web Fonts: Các font chữ được tải từ một domain khác và sử dụng trong trang web thông qua quy tắc
@font-face
trong CSS. - WebGL Texture: Các kết cấu (textures) được sử dụng trong đồ họa WebGL được tải từ một domain khác.
Hướng dẫn cách sử dụng Cors
Dưới đây là cách sử dụng Cors mà bạn có thể tham khảo:
Tạo truy vấn Cors với XMLHttpRequest
Bước 1: Tạo một đối tượng XMLHttpRequest thực hiện yêu cầu như sau:
var xhr = new XMLHttpRequest(); // Tạo một đối tượng XMLHttpRequest mới
Bước 2: Sử dụng phương thức open() để mở kết nối đến URL của tài nguyên trên domain khác. Trong đó, GET
được hiểu là phương thức yêu cầu HTTP, còn https://domain.com/data chính là domain của tài nguyên mà bạn cần truy cập.
xhr.open('GET', 'https://domain.com/data', true); // Mở kết nối GET đến URL đích, bất đồng bộ (true)
Bước 3: Thiết lập header cho Cors, với Content – Type là kiểu dữ liệu của request, còn Access – Control – Allow – Origin được dùng để chỉ định có nguồn được phép truy cập vào tài nguyên.
xhr.setRequestHeader('Content-Type', 'application/json'); // Đặt kiểu dữ liệu yêu cầu là JSON
xhr.setRequestHeader('Access-Control-Allow-Origin', '*'); // Cho phép tất cả các domain truy cập (hoặc chỉ định domain cụ thể)
Bước 4: Sử dụng phương thức send()
để gửi yêu cầu đến server.
xhr.send(); // Gửi yêu cầu đi
Bước 5: Xử lý phản hồi từ server bằng cách lắng nghe sự kiện onreadystatechange
. Khi yêu cầu hoàn thành (readyState === 4
), kiểm tra mã trạng thái (status). Nếu mã trạng thái là 200 (OK)
, thì phân tích dữ liệu JSON từ responseText
. Nếu có lỗi, in thông báo lỗi ra console.
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) { // Kiểm tra xem yêu cầu đã hoàn thành và thành công
var data = JSON.parse(xhr.responseText); // Phân tích dữ liệu JSON từ phản hồi
console.log(data); // In dữ liệu ra console (hoặc xử lý theo ý muốn)
} else if (xhr.readyState === 4) { // Nếu có lỗi
console.error('Lỗi khi tải dữ liệu:', xhr.status);
}
};
Tạo truy vấn Cors với jQuery
jQuery cung cấp một cách tiện lợi và đơn giản để thực hiện các truy vấn CORS thông qua hàm $.ajax()
. Hàm này tự động xử lý các header CORS cần thiết và hỗ trợ cả việc gửi cookie.
$.ajax({
url: 'https://domain-khac.com/api/dulieu',
type: 'GET', // Hoặc POST, PUT, DELETE
dataType: 'json', // Kiểu dữ liệu mong muốn (json, xml, text,...)
success: function(data) {
// Xử lý dữ liệu response ở đây
},
error: function(jqXHR, textStatus, errorThrown) {
// Xử lý lỗi ở đây
if (jqXHR.status === 0 && textStatus === 'error') {
// Có thể là lỗi CORS
console.error('Lỗi CORS:', errorThrown);
} else {
console.error('Lỗi khác:', textStatus, errorThrown);
}
}
});
Trong đó:
url
: URL của tài nguyên trên domain khác.type
: Phương thức HTTP (GET, POST, PUT, DELETE).dataType
: Kiểu dữ liệu mong muốn của phản hồi từ server.crossDomain
: Để bật Cors, bạn cần bậtcrossDomain
thànhtrue
.
Nếu request được thực hiện thành công, dữ liệu trả về sẽ có trong hàm success
. Trong trường hợp lỗi xảy ra, hàm error
sẽ được gọi để bạn phát hiện và xử lý. Ngoài ra, bạn cũng có thể thêm các header bổ sung tại headers
như sau:
$.ajax({
url: "https://api.example.com/data", // URL của API bạn muốn gọi
method: "GET", // Phương thức HTTP (GET, POST, PUT, DELETE, etc.)
headers: {
"Access-Control-Allow-Origin": "*", // Cho phép mọi origin truy cập (hoặc chỉ định origin cụ thể)
"Content-Type": "application/json" // Loại dữ liệu trả về là JSON (hoặc điều chỉnh theo API của bạn)
// Các header CORS bổ sung khác nếu cần
},
success: function(response) {
// Xử lý khi request thành công
console.log("Dữ liệu trả về:", response);
// Cập nhật giao diện người dùng, hiển thị dữ liệu, v.v.
},
error: function(xhr, status, error) {
// Xử lý khi có lỗi xảy ra
console.error("Lỗi:", error);
// Hiển thị thông báo lỗi cho người dùng, thực hiện các hành động khắc phục, v.v.
}
});
Trong ví dụ trên, header
sẽ chứa các header Cors bổ sung như Access-Control-Allow-Origin, Content-Type,…
Tạo truy vấn Cors với Fetch API
Fetch API là một giao diện lập trình ứng dụng (API) hiện đại và linh hoạt hơn so với XMLHttpRequest để thực hiện các yêu cầu HTTP, bao gồm cả truy vấn CORS. Fetch API được hỗ trợ bởi hầu hết các trình duyệt hiện đại (trừ IE).
fetch('https://domain-khac.com/api/dulieu')
.then(response => {
if (!response.ok) { // Kiểm tra trạng thái phản hồi
throw new Error('Lỗi mạng hoặc lỗi CORS: ' + response.status);
}
return response.json(); // Hoặc response.text() nếu dữ liệu là text
})
.then(data => {
// Xử lý dữ liệu response ở đây
console.log(data);
})
.catch(error => {
// Xử lý lỗi ở đây
console.error('Đã xảy ra lỗi:', error);
});
Giải thích:
fetch(url)
: Gửi yêu cầu HTTP đến URL được chỉ định và trả về một Promise..then(response => ...)
: Xử lý phản hồi (response) khi Promise được giải quyết..then(data => ...)
: Xử lý dữ liệu đã được chuyển đổi..catch(error => ...)
: Xử lý lỗi nếu có, ví dụ như lỗi mạng hoặc lỗi CORS.
So sánh sự khác nhau giữa CORS và JSONP
Cors và JSONP đều được sử dụng để giải quyết vấn đề giao tiếp giữa các ứng dụng web chạy trên domain khác nhau. Nhưng là hai kỹ thuật hoàn toàn khác biệt. Trong đó, JSONP là một kỹ thuật cũ và khá hạn chế so với Cors. Kỹ thuật này cho phép các ứng dụng web chạy trên domain khác nhau có thể giao tiếp với nhau một cách dễ dàng hơn.
Với JSONP, phương pháp này sử dụng các thẻ tập lệnh HTML trong máy khách để tải file JavaScript hoặc nhúng trực tiếp mã JavaScript vào trong trang HTML. Khi đó, vì các tập lệnh đều không tuân theo chính sách cùng nguồn gốc, nên người dùng có thể truy xuất dữ liệu dễ dàng bằng JavaScript.
Tuy nhiên, điểm hạn chế là dữ liệu ở đây phải thuộc định dạng JSON và tính bảo mật của JSONP cũng không được đảm bảo vì kỹ thuật này không áp dụng các biện pháp bảo mật mạnh mẽ để đảm bảo tính an toàn và chính xác của dữ liệu được truyền từ miền bên ngoài về máy khách (client). So với JSONP, Cors là cơ chế bảo mật hiện đại và an toàn hơn rất nhiều.
Ngày nay, các trình duyệt đã bổ sung nhiều tính năng bảo mật nâng cao nên các mã cũ chứa JSONP thường không còn hoạt động nữa. Thay vào đó, Cors đã trở thành một tiêu chuẩn toàn cầu được áp dụng rộng rãi trong việc kiểm soát truy cập giữa các ứng dụng web có nguồn khác khác nhau.
Các Framework hỗ trợ Cors như nào?
Dưới đây là một vài framework hỗ trợ cho cơ chế bảo mật Cors mà bạn có thể tham khảo:
Laravel CORS
Khi bạn lập trình một số ứng dụng dưới local và connect chúng tới Laravel backed, bạn sẽ nhận được thông báo error CORS ngay sau đó. Để tránh xảy ra điều này, bạn có thể tạo một middleware như sau:
$ php artisan make:middleware Cors
Sau đó, bạn cập nhật header trong app/Http/Middleware/Cors.php với:
<?php
namespace AppHttpMiddleware;
use Closure;
class Cors
{
public function handle($request, Closure $next)
{
return $next($request)
->header(‘Access-Control-Allow-Origin’, ‘*’)
->header(‘Access-Control-Allow-Methods’, ‘GET, POST, PUT, DELETE, OPTIONS’)
->header(‘Access-Control-Allow-Headers’, ‘X-Requested-With, Content-Type, X-Token-Auth, Authorization’);
}
}
Tại đây, bạn bắt đầu đăng ký middleware trong app/Http/kernel.php với:
protected $routeMiddleware = [
‘auth’ => AppHttpMiddlewareAuthenticate::class,
‘auth.basic’ => IlluminateAuthMiddlewareAuthenticateWithBasicAuth::class,
‘guest’ => AppHttpMiddlewareRedirectIfAuthenticated::class,
‘cors’ => AppHttpMiddlewareCors::class, // <-- thêm vào hàng này
];
Bây giờ, bạn chỉ cần add middleware này trong route registration để bật Cors cho bất kỳ route nào mình muốn. Ngoài ra, bạn cũng có thể sử dụng packgage ngoài tại barryvdh/laravel-cors.
CORS Nodejs
Để bật Cors, bạn cần set một header trên response với đoạn code sau:
res.header("Access-Control-Allow-Origin", "*");
Thông qua đoạn mã dưới đây, bạn có thể bật CORS cho toàn bộ resource trên server:
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
Để chỉ định file nào đó, hãy tham khảo đoạn code sau:
app.get('/file', function(req, res){
var file = __dirname + '/file.zip';
res.download(file); // Set disposition and send it.
});
Dưới đây là ví dụ đầy đủ cho bạn:
var express = require('express');
var app = express();
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.get('/', function (req, res) {
var data = {
"SmartPhone": [
"iPhone",
"Samsung" ]
};
res.json(data);
});
app.get('/file', function(req, res){
var file = __dirname + '/file.zip';
res.download(file); // Set disposition and send it.
});
Ruby on Rails
Với Ruby on Rails, bạn có thể cài đặt, thiết lập và thay đổi các header trong response một cách dễ dàng. Cách thực hiện khá đơn giản, nhưng trước đó bạn cần chấp nhận truy vấn Cors với:
skip_before_filter :verify_authenticity_token
before_action :cors_preflight_check
after_action :cors_set_access_control_headers
def cors_set_access_control_headers
headers["Access-Control-Allow-Origin"] = "*"
headers["Access-Control-Allow-Methods"] = "GET, POST"
headers["Access-Control-Max-Age"] = "1728000"
end
def cors_preflight_check
headers["Access-Control-Allow-Origin"] = "*"
headers["Access-Control-Allow-Methods"] = "GET, POST"
headers["Access-Control-Allow-Headers"] =
"X-Requested-With, X-Prototype-Version"
headers["Access-Control-Max-Age"] = "1728000"
end
Django
Để sử dụng Django, bạn cần có một package là Django CORS headers. Package này cho phép bạn xác định các header cần thiết cho truy vấn Cors. Đồng thời, thông qua đó, bạn còn có thể chỉ định URL nào cho phép hoặc không cho phép Cors.
Để làm được điều đó, bạn cần thiết lập cấu hình sao cho chỉ có API mới được hỗ trợ Cors với đoạn code sau:
CORS_ORIGIN_ALLOW_ALL = True
CORS_URLS_REGEX = r'^/api/v1/.*$'
Bên cạnh đó, còn có rất nhiều cách khác cho phép bạn chỉ định truy vấn Cors nào trong một vài origin được chấp nhận, chẳng hạn như CORS_ORIGIN_REGEX_WHITELIST
…
Flask
Với Flask, bạn cũng cần một package đi kèm là Flask-CORS để chấp nhận các truy vấn Cors:
from flask import Flask
from flask.ext.cors import CORS, cross_origin
app = Flask(__name__)
app.config['SECRET_KEY'] = 'The quick brown fox jumps over the lazy dog'
app.config['CORS_HEADERS'] = 'Content-Type'
cors = CORS(app, resources={r'/foo/*': {'origins': '*'}})
@app.route('/foo')
@cross_origin()
def foo():
return 'Hello, world! CORS works'
if __name__ == '__main__':
app.run()
Câu hỏi thường gặp
Câu hỏi thường gặp
Lỗi Cors là gì?
Lỗi Cors là một loại lỗi xảy ra khi trình duyệt web cố gắng thực hiện một yêu cầu HTTP từ một trang web tới một tài nguyên của domain khác. Đây là cơ chế bảo mật quan trọng được sử dụng trong các trình duyệt web để ngăn chặn các trang web độc hại không cùng nguồn (different domain) truy cập trái phép vào tài nguyên của một domain khác, từ đó bảo vệ dữ liệu và ngăn chặn các cuộc tấn công có thể xảy ra.
Cors Policy là gì?
Cors Policy là các chính sách Cors được áp dụng trong trình duyệt web để kiểm soát và quản lý chặt chẽ việc các trang web khác nhau truy cập vào tài nguyên trên cùng một trang web. Cors sẽ trao đổi thông tin giữa trình duyệt và server thông qua các tiêu đề HTTP, từ đó quyết định việc trang web kia có được truy cập vào tài nguyên của website hay không. Bằng cách đó, Cors đảm bảo rằng các trang web không thể tự do lấy dữ liệu của nhau khi chưa được cấp phép.
Trạm Cors là gì?
Trạm Cors là một thuật ngữ được sử dụng để chỉ mạng lưới các trạm tham chiếu GNSS (Global Navigation Satellite System) hoạt động liên tục tại những vị trí cố định trên khắp thế giới. Các trạm này có nhiệm vụ thu nhận và xử lý các tín hiệu từ vệ tinh để cung cấp thông tin, dữ liệu về vị trí, từ đó nâng cao độ chính xác cho các thiết bị định vị. Hiện nay, người dùng có thể tận dụng dữ liệu Cors bằng cách sử dụng phương pháp Real-Time Kinematic (định vị thời gian thực) hoặc xử lý sau khi thu thập dữ liệu.
Lời kết
Bên trên là câu trả lời cho thắc mắc Cors là gì và một số cách sử dụng Cors hiệu quả hiện nay. Ngoài ra, đừng quên chia sẻ bài viết để những ai quan tâm đến các cơ chế bảo mật web hàng đầu hiện nay có thể tham khảo và đón đọc, bạn nhé!