2012-06-17 28 views
12

Tôi đã xem xét trên Google và StackOverflow cho câu trả lời cho câu hỏi này, nhưng thực tế là tôi không biết nhiều về .htaccess không giúp tôi quyết định câu trả lời đúng cho tình hình của tôi, vì vậy tôi hỏi ở đây..htaccess RewriteCond nơi URI không chứa miền

Tình huống của tôi là tôi có một số trang web đang sử dụng cùng một thư mục vật lý làm thư mục gốc trên máy chủ.

Tất cả đều hoạt động tốt nhưng tôi muốn đảm bảo rằng mỗi trang web không thể truy cập từng hình ảnh khác từ trình duyệt trừ khi chúng nằm đúng tên miền.

Hiện nay tôi có một cấu trúc tập tin như thế này:

/resources/{resource}/{full_domain_name} 

Vì vậy, ví dụ www.domain.co.uk sẽ có một cấu trúc như thế này:

http://www.domain.co.uk/resources/images/www.domain.co.uk/some_image.jpg 

Nhưng nếu www.domain_2.co.uk tồn tại bằng cách sử dụng thư mục vật lý tương tự cho các trang web sau đó họ có thể xem tài nguyên của miền khác từ miền của riêng họ, như sau:

http://www.domain_2.co.uk/resources/images/www.domain.co.uk/some_image.jpg 

Đây thực sự không phải là vấn đề lớn vì hoàn toàn không có thông tin nhạy cảm được lưu trữ trong các thư mục này, nhưng nó gây phiền toái và tôi muốn người dùng không thể thực hiện được (không phải bất kỳ ai thực sự có).

Tôi đã thử đặt một tập tin .htaccess vào thư mục/nguồn lực nhưng tôi bị mắc kẹt với các biểu thức thông thường, vv

tôi về cơ bản muốn chắc chắn rằng URI chứa tên miền hiện tại bằng cách khác chuyển hướng đến một 403 trang lỗi.

Đây là những gì tôi đã đưa ra:

RewriteCond %{REQUEST_URI} !^(/resources/[^/]*/%{HTTP_HOST})(.*)$ 
RewriteRule ^(.*)$ /error/403.php 

Lý do tôi đưa vào các bit [^/] là bởi vì có một số thư mục, ví dụ:

/resources/images/{full_domain_name} 
/resources/scripts/{full_domain_name} 
/resources/stylesheets/{full_domain_name} 

Ai có thể giúp tôi với các điều kiện?

Mọi trợ giúp sẽ được đánh giá cao.

+0

Kết quả của quy tắc hiện tại của bạn là gì? Dường như nó sẽ hoạt động, ngoại trừ việc bạn không cần bất kỳ '()' xung quanh '/ resources/[^ /] * /% {HTTP_HOST}. *' –

+0

@Michael Hiện tại nếu tôi đang ở trên www.domain.co .uk và truy cập www.domain.co.uk/resources/stylesheets/www.domain.co.uk/style.css ví dụ: nó luôn chuyển hướng tôi đến tệp /error/403.php. Khi tôi loại bỏ các quy tắc .htaccess nó tìm thấy tập tin như nó phải làm bình thường. –

+0

Bạn không thực sự cần toàn bộ '% {REQUEST_URI}' đại diện trong regex. Bạn chỉ có thể so khớp http_host 'RewriteCond% {REQUEST_URI}! ^. +% {HTTP_HOST}' –

Trả lời

10

Đây là câu hỏi tuyệt vời và nếu tôi có thể tôi đã tăng gấp 10 lần. Tôi đăng câu trả lời của tôi ngay cả khi bạn có một câu trả lời được chấp nhận ở đây vì tôi thực sự phải đào sâu tất cả các tài nguyên Apache của tôi để đưa ra câu trả lời. Dưới đây là các quy tắc bạn sẽ cần cho vấn đề này:

Options +FollowSymLinks -MultiViews 
# Turn mod_rewrite on 
RewriteEngine On 
RewriteBase/

RewriteCond %{HTTP_HOST}:%{REQUEST_URI} !^([^:]+):/resources/[^/]+/\1/.+ [NC] 
RewriteRule ^resources/[^/]+/[^/]+/.+ - [F,NC,NE] 

PS: Vì chúng ta không thể sử dụng % biến trên RHS như back-tham khảo, tôi đang sử dụng regex đặc biệt trở lại tham chiếu biến \1 trong RewriteCond đây.

+1

Tôi không thường làm điều này nhưng trong trường hợp này tôi nghĩ rằng tôi sẽ thay đổi câu trả lời được chấp nhận của tôi, vì điều này cung cấp một giải pháp hoàn hảo cho vấn đề. Cảm ơn bạn đã đăng câu trả lời của bạn anubhava, nó được nhiều đánh giá cao! –

+0

Bạn được chào đón nhiều nhất và cảm ơn bạn đã đăng một bài viết thú vị như vậy đã khiến tôi học được các thủ thuật mod_rewrite mới :). – anubhava

3

Tình trạng này là đủ:

RewriteCond %{REQUEUST_URI} !^(/resources/[^/]*/%{HTTP_HOST})(.*)$ 

Bởi vì nếu tôi yêu cầu bất cứ điều gì mà không bắt đầu bằng /resources/, tôi sẽ nhận được trang 403.php lỗi. Những gì bạn thực sự muốn là một cái gì đó như thế này:

RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/ 
RewriteCond %{HTTP_HOST} !%1 

Hoặc

RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/ 
RewriteCond %{REQUEST_URI} !^/resources/[^/]+/%{HTTP_HOST}/ 

Trong trường hợp điều kiện đầu tiên là kiểm tra rằng yêu cầu là dành cho một tài nguyên, sau đó thứ hai kiểm tra máy chủ. HOWEVER, cả hai cách này đều không hoạt động vì chỉ thị RewriteCond của mod_rewrite không cho phép các biến số % hoặc ngược lại ở phía bên phải của điều kiện, chỉ bên trái.Tương tự như vậy, bạn không thể làm điều này một trong hai:

RewriteCond %{REQUEST_URI} ^/resources/[^/]+/([^/]+)/ 
RewriteRule !^/resources/[^/]+/%{HTTP_HOST}/ /error/403.php 

Bởi vì biểu hiện của RewriteRule không thể có các biến trong nó, vì nó là một regex, và nó theo nghĩa đen hy vọng một %{HTTP_HOST} thay vì thay thế nó bằng Host được đưa ra trong yêu cầu. Vì vậy, để kết luận, không, bạn không thể làm điều này với các điều kiện của mod_rewrite theo cách này.

Điều gì đó mà bạn có thể thử nếu bạn có quyền truy cập vào cấu hình máy chủ hoặc cấu hình vhost là tạo RewriteMap và chuyển vào cả hai số %{REQUEST_URI}%{HTTP_HOST}. Vì vậy, nếu bản đồ của bạn được gọi là check_host sau đó quy tắc của bạn có thể trông giống như thế này:

RewriteRule ^resources/[^/]+/([^/]+)/ ${check_host:%{HTTP_HOST}_%{REQUEST_URI}} 

Và kịch bản của bạn sẽ chỉ cần phải phân tích đầu vào, tách nó ra khỏi _ đầu tiên, phân tích yêu cầu URI và chắc chắn rằng máy chủ giống như HTTP_HOST. Nếu nó giống nhau, xuất ra cùng một URI yêu cầu, nếu không thì sẽ xuất ra URI lỗi. Nếu bạn không có quyền truy cập vào máy chủ hoặc cấu hình vhost, tôi nghĩ bạn đã hết may mắn. Không thể xác định RewriteMap trong tệp htaccess.

+0

Cảm ơn bạn đã trả lời câu trả lời này Jon Lin. Tôi không biết rằng bạn không thể đặt các biến% hoặc tham chiếu ngược vào bên phải của RewriteCond. Tôi đã chọn để thử RewriteMap nhưng nếu vì lý do nào tôi không thể làm điều đó thì tôi chắc chắn tôi sẽ tìm một cách khác bên ngoài mod_rewrite :) –

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