2012-02-01 30 views
28

Hãy theo tôi, điều này cần một chút giải thích.Thông tin đăng nhập cookie CORS từ WebView trên thiết bị di động được tải cục bộ bằng tệp: //

Tôi đang giúp xây dựng một ứng dụng web di động lai. Các codebase chính là HTML5 và JavaScript, mà sẽ được bao bọc trong một Web View di động bản địa (a la Phonegap).

Một phần chức năng yêu cầu ứng dụng đăng thông tin lên dịch vụ web do một trong những khách hàng của chúng tôi kiểm soát. Có rất ít phạm vi để thay đổi dịch vụ web này vì nó đang được người khác sử dụng. Chúng tôi gửi JSON bằng cách sử dụng HTTP POST và nhận phản hồi từ máy chủ. Một phần của phản hồi này là một cookie JSESSIONID quản lý phiên của chúng tôi với máy chủ. Sau cuộc gọi initSession() ban đầu, chúng tôi cần gửi cookie JSESSIONID với mọi yêu cầu (AJAX).

Khi được triển khai trên thiết bị di động, ứng dụng web được bao bọc trong Chế độ xem web gốc, khởi chạy ứng dụng web bằng cách duyệt đến file:///path/to/app/index.html.

Điều đầu tiên chúng tôi đã thử là yêu cầu khách hàng đặt Access-Control-Allow-Origin: * trong tiêu đề phản hồi của họ để cho phép CORS. Sau đó, chúng tôi đã cố đăng bài lên máy chủ:

$.ajax({ 
    url: 'http://thirdparty.com/ws', 
    data: data, 
    type: "POST", 
    dataType: "JSON", 
    success: successCallback, 
    error: failedCallback 
}); 

Giám sát các yêu cầu, rõ ràng là cookie không được đưa vào. Khi kiểm tra kỹ hơn, có special section in the CORS spec for dealing with user credentials, bao gồm cookie phiên. Vì vậy, tôi đã sửa đổi cuộc gọi AJAX để bao gồm điều này:

$.ajax({ 
    url: 'http://thirdparty.com/ws', 
    data: data, 
    type: "POST", 
    dataType: "JSON", 
    success: successCallback, 
    error: failedCallback, 
    xhrFields { withCredentials: true } 
}); 

Một lỗi khác, lần này từ Trình duyệt. Đọc thêm mang lại những điều sau đây:

Nếu máy chủ của bên thứ ba không phản hồi với tiêu đề Access-Control-Allow-Credentials: true, phản hồi sẽ bị bỏ qua và không được cung cấp cho nội dung web.

Lưu ý quan trọng: khi trả lời yêu cầu được chứng nhận, máy chủ phải chỉ định miền trong tiêu đề Access-Control-Allow-Origin và không thể sử dụng tính năng gắn thẻ tự nhiên.

Vì vậy, chúng tôi cần thay đổi tiêu đề của máy chủ để bao gồm Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin đối với Nguồn gốc của chúng tôi.

Ở đây chúng tôi cuối cùng đã gặp sự cố của mình: when loading a web page using the file:// protocol, tiêu đề yêu cầu Origin được gửi từ Chế độ xem web được đặt thành null. Do đó nó không thể được phân tích bởi máy chủ và do đó máy chủ không thể đặt nó trong Access-Control-Allow-Origin. Nhưng nếu máy chủ không thể đặt Access-Control-Allow-Origin thành một thứ khác không phải là *, chúng tôi không thể gửi bằng chứng xác thực, bao gồm cả cookie.

Vì vậy, tôi bị kẹt. Phải làm gì? I saw a similar question posted here nhưng tôi không thực sự hiểu câu trả lời được đề xuất. Bất kì sự trợ giúp nào đều được đánh giá cao!

+2

Giải pháp duy nhất tôi có thể nghĩ là sử dụng máy chủ để truy cập dịch vụ web. Bạn có thể viết trình xử lý HTTP và nhấn vào trình xử lý đó từ ứng dụng dành cho thiết bị di động của mình. Rõ ràng điều này cho biết thêm chi phí bổ sung trong bảo trì máy chủ nhưng bạn phải có một cái gì đó có sẵn, không? –

+0

Vâng, đó là giải pháp tạm thời, một cửa sổ trung gian curl php khó chịu. Nó thực sự không phải là lý tưởng, nhưng ít nhất là làm việc trong thời gian này. – fiznool

+0

Một điều tôi có thể làm là hỏi các nhà phát triển phonegap nếu họ đã thấy bất cứ điều gì như thế này trước đây và có cách giải quyết ... – fiznool

Trả lời

0

Hãy thử tìm kiếm tại www.5app.co.uk. Tránh sử dụng các cuộc gọi XHR hoàn toàn và hoạt động đáng tin cậy trên thiết bị di động khi kết nối dữ liệu đến và đi. Gateway sau đó giao tiếp với khách hàng của bạn.

+0

Cảm ơn thông tin. Lý tưởng nhất là tôi không tìm kiếm một sự thay đổi căn bản trong cách chúng tôi phát triển ứng dụng, nhưng tôi sẽ xem những gì 5app có thể cung cấp cho chúng tôi. – fiznool

0

Sử dụng yêu cầu JsonP. Yêu cầu JsonP cho phép bạn thực hiện yêu cầu miền chéo. Here là một ví dụ.

+0

'JSONP' sẽ chỉ hoạt động đối với các yêu cầu' GET'. –

7

Tôi nhận ra câu hỏi này là cũ, nhưng tôi nghĩ rằng tôi sẽ ném vào nó dù sao đi nữa. Trong trường hợp yêu cầu CORS, trình duyệt sẽ phát trước chúng. Điều này có nghĩa là - bất chấp phương thức $.ajax() nào bạn đang sử dụng, yêu cầu OPTIONS được gửi đến máy chủ.

Điều này preflighted OPTIONS yêu cầu được thực sự làm được nói:

"Hey ở đó, ngoại-server-từ-some-other-miền, tôi muốn gửi cho bạn một yêu cầu không-đơn giản (đơn giản của req không phải là preflighted). Yêu cầu không đơn giản của tôi sẽ có các loại tiêu đề và loại nội dung và vân vân. Bạn có thể cho tôi biết nếu điều này được không? "

Sau đó máy chủ sẽ làm bất cứ điều gì nó (có thể kiểm tra một số cấu hình cơ sở dữ liệu hoặc) và đáp ứng với nguồn gốc cho phép (s), tiêu đề cho phép (s), và/hoặc các phương pháp cho phép (s).

Cuối cùng - nếu preflight đó OPTIONS yêu cầu đã nhận được phản hồi cho phép phương thức $.ajax() thực tế đi - nó sẽ biến mất.

CORS không giống với JSONP.

Tất cả những gì nói - trong khi withCredentials thành công preflight đòi hỏi sự phản ứng để thực hiện một tiêu đề Access-Control-Allow-Credentials (như đã nêu trong câu hỏi), có nghĩa là ngoài việc Access-Control-Allow-OriginsAccess-Control-Allow-Methods giá trị, trong đó phải bao gồm các khía cạnh được yêu cầu mong muốn.

Ví dụ - nếu bạn đang thực hiện một CORS POST yêu cầu từ nguồn gốc http://foo-domain.com với tiêu đề somevalue-http://bar-domain.com, một OPTIONS yêu cầu preflight sẽ đi ra ngoài và để cho các bài yêu cầu thực tế phải được thực hiện để http://bar-domain.com, yêu cầu OPTIONS sẽ cần để nhận được phản hồi với giá trị Access-Control-Allow-Origins bao gồm http://foo-domain.com. Đây có thể là tên gốc hoặc *. Câu trả lời cũng sẽ cần có giá trị Access-Control-Allow-Methods bao gồm POST. Đây cũng có thể là *. Và Cuối cùng, nếu chúng tôi muốn cho phép tiêu đề somevalue của chúng tôi, phản hồi phải chứa giá trị Access-Control-Allow-Headers bao gồm khóa tiêu đề somevalue hoặc * của chúng tôi.

Để quay vòng lại - nếu bạn không thể điều khiển máy chủ hoặc không có cách nào cho phép máy chủ cho phép CORS yêu cầu, bạn luôn có thể sử dụng JSONP hoặc một số kiểu dữ liệu url được mã hóa và/hoặc thực hiện các yêu cầu đơn giản mà không cần tiêu đề tùy chỉnh. GET, HEAD và yêu cầu đầy đủ POST thường là các yêu cầu đơn giản.

+2

Lưu ý phụ: khi trả lời yêu cầu được chứng nhận, máy chủ phải chỉ định miền và không thể sử dụng tính năng gắn thẻ tự nhiên ('*'). –

1

Đề nghị của tôi được thiết lập ACCESS-CONTROL-ALLOW-ORIGIN để null về phía máy chủ

Vâng, câu hỏi này làm tôi bực mình cho một chút.

Về CORS spec, null có thể phục vụ các tình huống mà một yêu cầu CORS từ một chương trình file://

Và một khuyến nghị thiết thực trên spec mà là để thiết lập nó như origin-list-or-null, đó là một trong hai danh sách nguồn gốc không gian ly thân hoặc đơn giản là "vô giá trị" (bằng cách này, chuỗi %x6E %x75 %x6C %x6C từ định nghĩa cho origin-list-or-null là nghĩa đen null hex- mã hóa)

Cuối cùng bạn sẽ hỏi, sẽ không có tương đương với * nếu chúng ta đặt ACCESS-CONTROL-ALLOW-ORIGIN-null vì mọi yêu cầu từ lược đồ file:// đều hợp lệ (nghĩa là mọi ứng dụng lai có thể truy cập điểm cuối của bạn nếu nó biết về uri của bạn)?

Vâng, được cung cấp Access-Control-Allow-Credentials: true, tôi tin rằng bạn đã có toàn bộ cơ chế xác thực đang hoạt động trên máy chủ. Bạn nên lọc những yêu cầu đó mà không có đúng auth

Hy vọng nó sẽ giúp

Các vấn đề liên quan