apache wsgi, proxy, ssl 사용시 문의

안녕하세요?
저는 PHP 아마츄어 제작자인데, 2~3년전 부터 파이썬에 관심을 갖게되어
님의 저서를 비롯하여 몇 권의 서적을 뒤적이며 공부하게 되었고,
파이썬 프로그램에 익숙해 지고자 기존에 제작하여 운영중인 PHP 웹 프로그램을
플라스크를 사용하여 완전히 새로 만들었습니다.
localhost에서는 문제없이 작동하는데, 기존 PHP 웹 프로그램이 담겨있는
임대 서버에 올리는 것에서 몇 달을 소비하고 있습니다. (님의 저서가 apache를 예로 들었으면 좋았을텐데요.. ^^)

몇 달간 여러가지 난관을 거쳐오며, 이제 거의 해답 즈음에 다가선 것 같은데,
마지막 남은 문제는 파이썬 커뮤니티에서 찾아야 할 것 같습니다.
(국내에선 파이썬 질의응답 커뮤니티가 너무 부족하게 느껴져요..ㅠㅠ)

문의 드릴께요..

기존 웹서버는 아파치로 http://abc.com/~ 을 보내면 ssl이 적용되어 https://abc.com/~ (/var/www/html/) 에 있는
PHP 프로그램이 실행됩니다.

플라스크로 새로운 앱을 만들었고 위치는 (/var/www/py/) 입니다.
원하는 것은 url에 "/py/"를 붙일 경우(https://abc.com/py/~) apache proxy에서 5000번 포트로 연결하여
wsgi로 연결된 플라스크 앱이 실행되는 것입니다. 여기까지는 성공하였습니다만,
이후 플라스크 앱에서 리다이렉션 할 경우
http://abc.com/~ 을 호출하여 PHP 경로로 들어가서 오류가 나고,
"/py/"를 붙여야 진입하는 플라스크로 다시 돌아가지 않는다는 것 입니다.
플라스크에서 경로를 지정할 때 url 접두어로 "/py/"을 붙일 방법이 있을 것 같은데..... 모르겠네요..
참고로 http://abc.com:5000 으로 접속할 때는 localhost처럼 모든 플라스크 프로그램이 원활하게 작동합니다.
(https://abc.com:5000 은 안되는데, ssl을 사용해야 하므로 http:// 경로는 허용하지 말아야 합니다.)

아래는 제 소스입니다. 현재 운영중인 서버이므로 도메인은 abc.com으로 임의 수정해서 올립니다.

■ 디렉토리 구조

var
 └ www
     └ html         : php 프로젝트 디렉토리
     └ py           : python 디렉토리
        └ python     : python 패키지 디렉토리
        └ py         : python flask 프로젝트

■ httpd.conf

Listen 443                                     # ssl.conf 내용

<VirtualHost *:443> 
  DocumentRoot "/var/www/html" 
  ServerName abc.com:443 
  ServerAdmin admin@abc.com

  SSLEngine on                                 # http://  ->  https://
    <Location /py>                             
      ProxyPass http://abc.com:5000/           # abc.com/py/   ->  abc.com:5000   (-> flask 프로세스)
      ProxyPassReverse http://abc.com:5000/
    </Location>
  SSLProxyEngine on 
  SSLProtocol all -SSLv3

  SSLCertificateFile "/usr/sbin/conf/ucert/abc.com.crt" 
  SSLCertificateKeyFile "/usr/sbin/conf/ucert/abc.com.key" 
  SSLCertificateChainFile "/usr/sbin/conf/ucert/abc.com_ChainBundle.crt" 
  SSLCACertificateFile "/usr/sbin/conf/ucert/ADDTRUST_EXTERNAL_CA_ROOT.crt" 
</VirtualHost>                         

Listen 80                                     # httpd.conf 내용
NameVirtualHost *:80

<VirtualHost *:80>
  DocumentRoot /var/www/html
  ServerName abc.com                          # http://abc.com  -> https://abc.com   -> /var/www/html/   경로의 php 프로세스 실행
  ServerAlias www.abc.com                     # http://www.abc.com  -> https://abc.com   -> /var/www/html/   경로의 php 프로세스 실행
  php_flag register_globals on

  ProxyRequests Off
  ProxyPreserveHost On

  <Location /py>                              # http://abc.com/py/  -> https://abc.com/py/  -> abc.com:5000  ->  /var/www/py/ 경로의 flask 프로세스 실행
    ProxyPass https://abc.com:5000/
    ProxyPassReverse https://abc.com:5000/
  </Location>

</VirtualHost>

Listen 5000
<VirtualHost *:5000>                          # abc.com:5000 일 경우
  ServerName py.abc.com
  DocumentRoot /var/www/py
  WSGIDaemonProcess py user=apache group=apache processes=5 threads=5 python-home=/var/www/py python-path=/var/www/py/bin:/var/www/py/lib64/python3.6/site-packages:/var/www/py/lib/python3.6/site-packages
  WSGIProcessGroup py
  WSGIApplicationGroup %{GLOBAL}
  WSGIScriptReloading On
  WSGIScriptAlias / /var/www/py/py.wsgi       # /var/www/py/  경로의 flask app 가동

  <Directory /var/www/py>
    Order allow,deny
    Allow from all
  </Directory>
    Alias /static /var/www/py/py/static      # flask에서  /static 의 경로는  /var/www/py/py/static    bootstrap 및 css 파일 경로

  <Directory /var/www/py/py/static>
    Order allow,deny
    Allow from all
  </Directory>
</VirtualHost>

■ py.wsgi

import sys

sys.path.insert(0, "/var/www/py")
sys.path.append("/var/www/py/lib/python3.6/site-packages")
sys.path.append("/var/www/py/lib64/python3.6/site-packages")

from py import create_app
application = create_app()

■ flask login.py

from flask import Blueprint, render_template, request, session, redirect, url_for
from checker import check_logged_in      #session['id']를 확인하여 로그인 유무 파악
from DBcm import UseDatabase, ConnectionError, CredentialsError, SQLError   #데이타베이스 연동 모듈

bp = Blueprint('login',__name__,url_prefix='/')
log = Log()

@bp.route('/')
@bp.route('/login', methods=['POST', 'GET'])
def login() -> str:
    if request.method == 'GET':
        return render_template('/login.html')
    elif request.method == 'POST':
        user_id = request.form['id']
        user_pw = request.form['pw']
        with UseDatabase('dict') as cursor:
            _SQL = f"""
                select id,pw,admin_pw,secret,active,nickname,move_from 
                from user 
                where id='{user_id}' and (pw='{user_pw}' or admin_pw='{user_pw}')
                """
            cursor.execute(_SQL)
            row = cursor.fetchone()
            if row is None:
                return redirect('login')    
            else :
                session['id'] = row['id']
                if row['admin_pw'] == user_pw:
                    session['admin'] = True
                else:
                    session['admin'] = False
                return redirect('/main_list')   #여기를 "/py/main_list"로 해도 안되더군요

    return render_template('/login.html')

윤찬석 151

M 2022년 1월 10일 9:40 오전

목록으로
3개의 답변이 있습니다. 1 / 1 Page

여러가지 방법이 있네요.
다음을 참고해 보세요.

https://stackoverflow.com/questions/18967441/add-a-prefix-to-all-flask-routes

박응용

2022년 1월 10일 9:52 오전

윤찬석

M 2022년 1월 10일 4:51 오후