使用OpenShift代理的Yii2重定向

时间:2019-07-07 08:53:06

标签: php nginx yii2 openshift

我已经在Yii2上部署了基于PHP的{​​{1}}应用程序。基本上,OpenShift在基于Yii2且已安装alpinePHP的容器中运行。容器公开Nginx,然后将其绑定到port 8080服务,在该服务中依次创建带有OpenShift的安全路由。

大多数应用程序都可以正常工作,但是在进行Edge encryption发布以及稍后在控制器中进行重定向时,HTTP重定向到Yii2而不是停留在http://<sitename> ,导致该应用程序无法正常工作。 https请求本身可以工作,因为随后对数据库进行了更改,它的重定向返回到在这种情况下不起作用的概述。

控制器动作非常简单和标准:

POST

有关OpenShift配置的一些信息:

public function actionUpdate($id)
{
    $model = $this->findModel($id);

    if ($model->load(Yii::$app->request->post()) && $model->save()) {
        return $this->redirect(['index']);
    }

    return $this->render('update', [
        'model' => $model,
    ]);
}

用于创建应用程序的Dockerfile并不十分出色,它基本上安装了~ oc get routes NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD backend backend.apps.<instance> backend backend edge None frontend frontend.apps.<instance> frontend frontend edge None ~ oc describe route backend Name: backend Namespace: <project> Created: 10 hours ago Annotations: openshift.io/host.generated=true Requested Host: backend.apps.<instance> exposed on router router 10 hours ago Path: <none> TLS Termination: edge Insecure Policy: <none> Endpoint Port: backend Service: backend Weight: 100 (100%) Endpoints: <ip>:8080 PHP并设置了一些权限。 Nginx配置实际上可能是问题的一部分,在下面发布了经过清理的版本。

Nginx

编辑1:

在Nginx配置中添加以下行使其可以工作,但是它不是一个很好的解决方案:

worker_processes  1;
error_log stderr warn;
pid /run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main_timed  '$remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '"$http_user_agent" "$http_x_forwarded_for" '
                            '$request_time $upstream_response_time $pipe $upstream_cache_status';

    access_log /dev/stdout main_timed;
    error_log /dev/stderr notice;

    keepalive_timeout  65;

    server {
        listen [::]:8080 default_server;
        listen 8080 default_server;
        server_name _;

        sendfile off;

        root /var/www/html/backend/web/;
        index index.php index.html;

        location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to index.php
            try_files $uri $uri/ /index.php?q=$uri&$args;
        }

        # redirect server error pages to the static page /50x.html
        #
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root /var/lib/nginx/html;
        }

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_pass  127.0.0.1:9000;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_param SCRIPT_NAME $fastcgi_script_name;
            fastcgi_index index.php;
            include fastcgi_params;
        }

        location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
            expires 5d;
        }

        # deny access to . files, for security
        #
        location ~ /\. {
            log_not_found off;
            deny all;
        }

        # allow fpm ping and status from localhost
        #
        location ~ ^/(fpm-status|fpm-ping)$ {
            access_log off;
            allow 127.0.0.1;
            deny all;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
            fastcgi_pass 127.0.0.1:9000;
        }
    }
}

但是,这假定始终使用HTTP。但是,这取决于OpenShift路由的配置。是否有更好的(更通用的)解决方案?

2 个答案:

答案 0 :(得分:1)

OpenShift路由器(公开您创建的安全路由的路由器)将在请求上为运行Yii2应用程序的后端Pod设置多个headers

我们要做的第一件事是在Nginx上信任这些标头,以便将它们转发到后端Yii2应用程序。

location ~ \.php$ {
    proxy_pass_header   X-Forwarded-Proto;
    proxy_pass_header   X-Forwarded-Host;
    proxy_pass_header   X-Forwarded-Port;
    [...]

X-Forwarded-Proto将设置为https,并且看来Yii2将正确处理标头,但我之前从未使用过该PHP框架。如果需要的话,这将是第二步,这将使框架工艺响应URL带有x-forward-proto头中的协议。

此处应注意,如果不受信任的用户可以直接访问Nginx,则在Nginx级别信任这些标头可能很危险。在这种情况下,他们将能够欺骗请求并将这些标头设置为所需的任何内容。

答案 1 :(得分:1)

感谢所有评论和答案,我得以弄清楚。我不是在这里使用Nginx作为代理,而是在使用FastCGI for PHP,这就是为什么我不确定Jason提出的答案是否可行的原因。以下解决方案对我有用:

location ~ \.php$ {

    set $my_https 'off';
    if ($http_x_forwarded_proto = 'https') {
        set $my_https 'on';
    }

    fastcgi_param HTTPS $my_https;

也许有一个更优雅的解决方案,但是这个对我有用