Redirect Nginx berdasarkan agen pengguna

15

Ini adalah nginx conf saya saat ini:

server {
  listen 90;
  server_name www.domain.com www.domain2.com;
  root /root/app;
  location / {
    try_files $uri =404;
  }
  location ~ /([-\w]+)/(\w+)/ {
    proxy_pass bla bla
  }
}

berfungsi dengan baik, keduanya www.domain.comdan www.domain2.commelayani konten yang sama.

sekarang saya ingin menambahkan

jika pengguna mengunjungi www.domain.com dan agen pengguna adalah xxx lalu redirect ke www.domain2.com

Saya sudah mencari dan mencoba banyak metode tetapi tidak satupun yang berhasil.

wong2
sumber
Apakah Anda masih ingin menyajikan konten yang sama, bahkan setelah pengalihan?
Pothi Kalimuthu
@ Pati ya, tepatnya
wong2
Baik. Silakan periksa jawaban saya.
Pothi Kalimuthu

Jawaban:

12

Ada dua cara untuk memperbaiki masalah ini.

  1. Memiliki dua blok "server" yang terpisah untuk www.domain.com & www.domain2.com dan tambahkan baris aturan berikut ke blok "server" www.domain.com. Ini adalah cara yang disarankan untuk mengatasi masalah ini.

    if ($http_user_agent ~* "^xxx$") {
       rewrite ^/(.*)$ http://www.domain2.com/$1 permanent;
    }
    
  2. Jika Anda ingin mengelola pengalihan dengan satu blok "server" untuk kedua domain, Coba aturan di bawah ini

    set $check 0;
    if ($http_user_agent ~* "^xxx$") {
        set $check 1;
    }
    if ($host ~* ^www.domain.com$) {
        set $check "${check}1";
    }
    if ($check = 11) {
        rewrite ^/(.*)$ http://www.domain2.com/$1 permanent;
    }
    
serverliving.com
sumber
Kutipan langsung dari nginx.com/resources/wiki/start/topics/depth/ifisevil ... "Satu-satunya hal aman 100% yang dapat dilakukan di dalam jika dalam konteks lokasi adalah: kembali dan tulis ulang".
Pothi Kalimuthu
6

Langkah 1: Memiliki dua blok server, masing-masing satu untuk domain.com dan domain2.com.

Langkah 2: Gunakan jika benar karena jahat jika digunakan secara tidak benar.

Inilah solusi lengkapnya ...

server {
  listen 90;
  server_name www.domain.com;
  root /root/app;

  # redirect if 'xxx' is found on the user-agent string
  if ( $http_user_agent ~ 'xxx' ) {
    return 301 http://www.domain2.com$request_uri;
  }

  location / {
    try_files $uri =404;
  }
  location ~ /([-\w]+)/(\w+)/ {
    proxy_pass bla bla
  }
}

server {
  listen 90;
  server_name www.domain2.com;
  root /root/app;
  location / {
    try_files $uri =404;
  }
  location ~ /([-\w]+)/(\w+)/ {
    proxy_pass bla bla
  }
}
Pothi Kalimuthu
sumber
Alih-alih 301, Anda dapat menggunakan 302 juga, tergantung pada kasus penggunaan Anda.
Pothi Kalimuthu
hmm, saya pikir solusi ini mengandung terlalu banyak kode duplikat
wong2
Ada beberapa cara untuk menyelesaikan masalah. Saya memposting solusi saya hanya untuk membuat Anda melihat logika di balik bagaimana hal itu bisa diselesaikan. Ada beberapa cara untuk menghindari duplikat.
Pothi Kalimuthu
4

Cara yang disarankan mungkin akan menggunakan map, juga karena variabel-variabel ini dievaluasi hanya ketika mereka digunakan.

Juga penggunaan return 301 ...lebih disukai daripada penulisan ulang, karena tidak ada ekspresi reguler yang harus dikompilasi.

Di sini contoh di mana host dan agen-pengguna sebagai string gabungan dibandingkan dengan regex tunggal:

map "$host:$http_user_agent" $my_domain_map_host {
  default                      0;
  "~*^www.domain.com:Agent.*$" 1;
}

server {
  if ($my_domain_map_host) {
    return 302 http://www.domain2.com$request_uri;
  }
}

Dan ini bisa menjadi lebih fleksibel, misalnya jika tidak ada 2 tetapi lebih banyak domain yang terlibat.

Di sini kami memetakan www.domain.comdengan agen-pengguna yang dimulai dengan Agentke http://www.domain2.comdan www.domain2.comdengan agen-pengguna yang tepat Other Agentuntuk http://www.domain3.com:

map "$host:$http_user_agent" $my_domain_map_host {
  default                             0;
  "~*^www.domain.com:Agent.*$"        http://www.domain2.com;
  "~*^www.domain2.com:Other Agent$"   http://www.domain3.com;
}

server {
  if ($my_domain_map_host) {
    return 302 $my_domain_map_host$request_uri;
  }
}

NB, Anda membutuhkan nginx 0.9.0 atau lebih tinggi agar string bersambung di peta berfungsi.

Koen.
sumber