How can I test https connections with Django as easily as I can non-https connections using 'runserver'?

后端 未结 9 923
生来不讨喜
生来不讨喜 2020-11-28 17:55

I have an application that uses \"secure\" cookies and want to test it\'s functionality without needing to set up a complicated SSL enabled development server. Is there any

9条回答
  •  抹茶落季
    2020-11-28 18:08

    One way is using ngrok.

    1. Install ngrok. download link: https://ngrok.com/download

    2. Issue following command on terminal

      ngrok http 8000
      

    It will start ngrok session. It will list two urls. One is mapped to http://localhost:8000. Second is mapped to https://localhost:8000. Please check the screenshot below. Use either url. It will map to your local server.


    Second method is as per the the solution provided by @EvanGrim. Link - https://stackoverflow.com/a/8025645/9384511

    First method is preferred if you need to test https url just couple of times. But if your requirement says https is mandatory then it would be better if you follow second method. I faced following issues with @EvanGrim solution

    1. When accessing https url via requests, you will get subAltNames missing warning. This should not be a problem. Your url should work fine.
    2. You will not be able to access https url via android volley. It will throw error - your ip or localhost is not verified. Something like that.

    I solved these issues by adding subAltname to ssl certificate. Below is the steps I followed to run a local https server without the above two issues.

    1. Install stunnel. stunnel version used is version4(/usr/bin/stunnel4) For ubuntu execute

       sudo apt-get install stunnel
      
    2. Create directory stunnel in your Django Project.

    3. Copy openssl.cnf from /etc/ssl/openssl.cnf or /usr/lib/ssl/openssl.cnf to stunnel. Avoid editing them directly unless you know what you are doing.

      1. Search for [ req ] or [req] section.In req section set

         x509_extensions = v3_ca 
         req_extensions = v3_req 
        

        x509_extensions and req_extensions should be present. If not, add it. If commented, uncomment it.

      2. Search for [v3_req] section. In this section add

         subjectAltName = @alt_names
        
      3. Search for [v3_ca] section. In this section add

         subjectAltName = @alt_names
        
      4. We need to add a new section alt_names. This can be added any where. I added after [v3_ca] section. For local host and your ip address add as follows:

         [alt_names]
         DNS.1 = localhost
         IP.1 = x.x.x.x
         IP.2 = 127.0.0.1
        
    4. To create key execute

       openssl genrsa 1024 > stunnel.key
      
    5. To create DER encoded certificate execute either first or second command

      1. If you have directly edited /etc/ssl/openssl.cnf or /usr/lib/ssl/openssl.cnf

         openssl req -new -x509 -nodes -sha1 -days 365 -key stunnel.key > stunnel.cert
        
      2. If you have made copy of openssl.cnf in stunnel directory.

         openssl req -new -x509 -nodes -sha256 -days 365 -key stunnel.key -config openssl.cnf > stunnel.cert
        
    6. To create PEM ecoded certificate execute.

       cat stunnel.key stunnel.cert > stunnel.pem
      
    7. Create a config file for stunnel called dev_https.config with the following contents.

       #not to use pid
       pid=
       #path of certificate file
       cert = stunnel/stunnel.pem
       #version of SSL to use
       sslVersion = TLSv1.1
       foreground = yes
       #log output path
       output = stunnel.log
      
       [https]
       #listen on port 8443
       accept=8443
       #tunnel the connection to port 8001
       connect=8001
       # and close connection automatically after one second
       TIMEOUTclose=1
      

      Please note sslVersion is based on OpenSSL version used by python interpreter. Mine is OpenSSL 1.1.1. For this version use TLSv1.1. Find out your openssl version and add corresponding version. You can find out the OpenSSL version by executing

       python -c "import ssl; print(ssl.OPENSSL_VERSION)"
      
    8. Create a script called runserver and add below contents. This script should reside in same directory as manage.py This script will run two stunnel and two django environment. One for http connections and one for https connections. The issue of runserver not exiting cleanly(As mentioned by Evan) is solved by trap statement in which cleanup function is called.

       stunnel4 stunnel/dev_https.config &
       stunnel_pid=$!
       echo "stunnel pid: $stunnel_pid"
       python manage.py runserver 0.0.0.0:8000 &
       py_server_bg=$!
       echo "BG py server pid: $py_server_bg"
       HTTPS=1 python manage.py runserver 0.0.0.0:8001
      
       function cleanup()
       {
         echo "Cleaning up"
         kill $stunnel_pid
         kill $py_server_bg
         echo "Cleaned"
       }
      
       trap cleanup EXIT
      
    9. Execute

       chmod a+x runserver
      
    10. From you django project execute

      ./runserver
      
    11. Now if you execute a python requests command, subjectAltNames missing warning will not be displayed. Also your android volley https request will execute fine.

      data = {'login_id':'someid'}
      headers = {'content-type': 'application/json'}
      url = "https://localhost:8443/myauth/check-id/"
      r=requests.post(url, data=json.dumps(data), headers=headers,verify='stunnel/stunnel.pem')
      

    I would like to thank @EvanGrim for the solution. And Thanks to @Friek, @Utku and @dr. Sybren. Based on their comments I implemented cleanup function.

提交回复
热议问题