Fail to validate URL in Facebook webhook subscription with python flask on the back end and ssl

匿名 (未验证) 提交于 2019-12-03 08:46:08

问题:

I'm trying to start using new messenger platform from FB. So i have server with name (i.e.) www.mysite.com I got a valid SSL certificate for that domain and apache is setup correctly - all good.

I have a python code on my server which runs flask and i point it to these certificates I got for the server:

from flask import Flask, request from pymessenger.bot import Bot import requests import ipdb from OpenSSL import SSL app = Flask(__name__) TOKEN = "<access_token>" bot = Bot(TOKEN)  @app.route("/webhook", methods = ['GET', 'POST']) def hello():     if request.method == 'GET':         if (request.args.get("hub.verify_token") == "my_awesome_token"):                 return request.args.get("hub.challenge")     if request.method == 'POST':         output = request.json         event = output['entry'][0]['messaging']         for x in event:             if (x.get('message') and x['message'].get('text')):                 message = x['message']['text']                 recipient_id = x['sender']['id']                 bot.send_text_message(recipient_id, message)             else:                 pass         return "success"   if __name__ == "__main__":     # tried this - no luck     #context = SSL.Context(SSL.SSLv23_METHOD)     #context.use_privatekey_file('/home/mysite.com.key')     #context.use_certificate_file('/home/intermediate.crt')      # tried this - also same result     context = ('/mysite.com.crt', '/mysite.com.key')      app.run(host='www.mysite.com',port=5002, debug=True, ssl_context=context) 

It starts without error and if I navigate with my browser - i see it gets connections.

port 5002 is open inf my firewall.

But when I go to FB and try to subscribe to that URL - it keeps failing with this error:

The URL couldn't be validated.  Callback verification failed with the following errors: curl_errno = 60; curl_error = SSL certificate problem: unable to get local issuer certificate; HTTP Status Code = 200;  HTTP Message = Connection established 

I've read half the internet on the possible reasons and saw many different suggestions, but I can't make any of those work - i end up with the same result 95% of the time. 5% - some other error due to Flask bugging out with some "crazy" settings I try.

What can be wrong? I'm using certificate files which I got from COMODO. Also tried in the call back url to use /webhook - no luck either. same error.

回答1:

Add the issuer certificate also. Comodo will issue their own certificate. YOu need to include that while starting the server.



回答2:

As mentioned in the answer above, the issue is that you do not have the issuer certificate which means that a secure connection can not be established. These certificates can be downloaded from your certificate provider, in your case Comodo. Once you have them you need to serve both to the user so a SSL connection can be established. There are multiple ways to do depending on how you are hosting but the easiest way to do it is to concat the certificates together. The order they are concated in IS important and will cause a Key Mismatch error if done in the incorrect order. Your certificate should be first, followed by the issuer certificate and the root certificate, like this:

-----BEGIN CERTIFICATE----- (Your Primary SSL certificate: your_domain_name.crt) -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- (Your Intermediate certificate: Intermediate.crt) -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- (Your Root certificate: TrustedRoot.crt) -----END CERTIFICATE----- 

This can easily be done from the CLI like this:

cat your_domain_name.crt Intermediate.crt TrustedRoot.crt > combined.crt 

This command combines the 3 files in the proper order and stores the output in a new file called combined.crt. See here for more details.



回答3:

I use certbot and Let's Encrypt.

Follow Installing Client software.

Then run command => sudo ./certbot-auto --apache -d YOUR_DOMAIN_NAME.COM (i tried apache, nginx and flask alone, all works, no need to put https at front)

cd /etc/letsencrypt/live/YOUR_DOMAIN_NAME.COM/

context = ('/etc/letsencrypt/live/YOUR_DOMAIN_NAME.COM/fullchain.pem', '/etc/letsencrypt/live/YOUR_DOMAIN_NAME.COM/privkey.pem')

i used cert.pem instead of fullchain.pem at first and got the above error, succeed after changed cert.pem to fullchain.pem



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!