突然想开发一个微信公众号,就算没人关注也可以平时自己拿来使用,于是想到了用Flask做公众号的后端,用nginx来反向代理,并启用SSL/TLS。
下面分节介绍搭建过程。

安装python环境

自己平时用的python3,于是就用python3来搭的,ubuntu默认安装了python3,首先安装包管理

1
2
sudo apt install python3-pip
pip3 install --upgrade pip

然后安装virtualenv与其他库

1
2
3
4
5
pip3 install virtualenv
mkdir flask_app
cd flask_app
virtualenv env
source env/bin/activate

创建requirements.txt文件
如果想让Gunicorn支持异步 workers 的话需要安装一下三个python包(greenlet,eventlet,gevent),在清单文件中已给出,gunicorn还需要库函数 libevent(1.4.x or 2.0.4)
下面是Flask常用的库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Flask==0.10.1
Flask-Login==0.2.11
Flask-Mail==0.9.1
Flask-Moment==0.4.0
Flask-PageDown==0.1.5
Flask-SQLAlchemy==2.0
Flask-Script==2.0.5
Flask-WTF==0.10.2
Flask-Cache==0.13.1
Flask-Restless==0.15.0
Flask-Uploads==0.1.3
Jinja2==2.7.3
Mako==1.0.0
Markdown==2.5.1
MarkupSafe==0.23
SQLAlchemy==0.9.8
WTForms==2.0.1
Werkzeug==0.9.6
html5lib==1.0b3
itsdangerous==0.24
six==1.8.0
awesome-slugify==1.6
gevent==1.2.2
eventlet==0.22.1
greenlet==0.4.13
gunicorn==19.7.0

这么多要安装的库,一个一个得装非常麻烦,运行

(env) root@ubunt:~/flask_app# pip install -r requirements.txt

即可全部安装完成

项目文件

接下来就是上传 Flask的项目文件,这里先使用最简单的Flask应用

(env) root@ubunt:~/flask_app# vim run.py

1
2
3
4
5
6
7
8
9
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
return "Hello World!"
if __name__ == '__main__':
app.run(host='127.0.0.1',port=5000)

然后运行gunicorn

1
2
3
4
5
6
7
8
(env) root@ubunt:~/flask_app# gunicorn -w 4 -b 127.0.1:5000 run:app
[2018-03-11 03:24:02 +0000] [19339] [INFO] Starting gunicorn 19.7.0
[2018-03-11 03:24:02 +0000] [19339] [INFO] Listening at: http://127.0.0.1:5000 (19339)
[2018-03-11 03:24:02 +0000] [19339] [INFO] Using worker: sync
[2018-03-11 03:24:02 +0000] [19342] [INFO] Booting worker with pid: 19342
[2018-03-11 03:24:02 +0000] [19343] [INFO] Booting worker with pid: 19343
[2018-03-11 03:24:02 +0000] [19344] [INFO] Booting worker with pid: 19344
[2018-03-11 03:24:02 +0000] [19345] [INFO] Booting worker with pid: 19345

安装配置nginx

安装nginx

(env) root@ubunt:~/flask_app# apt install nginx

修改nginx配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(env) root@ubunt:~/flask_app# vim /etc/nginx/sites-available/default 

server {
listen 80 default_server;
listen [::]:80 default_server;

location / {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect default;
}
}

修改配置文件后,重启nginx服务

(env) root@ubunt:~/flask_app# /etc/init.d/nginx restart

此时打开浏览器,输入http://你的服务器ip就可以看到运行结果

现在基本配置就已经弄好了

开启SSL

nginx下配置ssl是很简单的,无论是去认证中心买SSL安全证书还是自签署证书,我自己是用的cloudflare的免费SSL证书,在cloudflare上的操作就不介绍了,在cloudflare上申请证书后会有一个公钥和密钥,把这两个保存到本地,接下来就直接介绍配置SSL
我自己的证书是放在/etc/ssl/private/目录里面的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name ***; #你的域名;

ssl on;
ssl_certificate /etc/ssl/private/***.crt; #公钥地址
ssl_certificate_key /etc/ssl/private/***.key; #私钥地址

location / {
proxy_pass http://localhost:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect default;
}
}

修改配置文件后,重启nginx服务

(env) root@ubunt:~/flask_app# /etc/init.d/nginx restart

flask接入微信公众号

首先,需要写 flask 后台代码,以下以一个简单的后台做为示范。

(env) root@ubunt:~/flask_app# vim run.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# -*- coding=utf-8 -*-
import time
from flask import Flask,g,request,make_response
import hashlib
import xml.etree.ElementTree as ET

app = Flask(__name__)

@app.route('/',methods=['GET','POST'])
def wechat_auth():
if request.method == 'GET':
token='Your token' #微信配置所需的token
data = request.args
signature = data.get('signature','')
timestamp = data.get('timestamp','')
nonce = data.get('nonce','')
echostr = data.get('echostr','')
s = [timestamp,nonce,token]
s.sort()
s = ''.join(s)
return make_response(echostr)
else:
rec = request.stream.read()
xml_rec = ET.fromstring(rec)
tou = xml_rec.find('ToUserName').text
fromu = xml_rec.find('FromUserName').text
content = xml_rec.find('Content').text
xml_rep = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content><FuncFlag>0</FuncFlag></xml>"
response = make_response(xml_rep % (fromu,tou,str(int(time.time())), content))
response.content_type='application/xml'
return response
return 'Hello weixin!'

if __name__ == '__main__':
app.run(debug=True)

然后运行gunicorn

(env) root@ubunt:~/flask_app# gunicorn -w 4 -b 127.0.1:5000 run:app

注: 其中的

1
response = make_response(xml_rep % (fromu,tou,str(int(time.time())), content))# 是将xml_rep 的值按顺序返回给微信

这个是返回值。所以如果要做什么微信自动回复就将内容添到content中,然后微信前端就会回复给用户。
注: 如果要消息加解密方式设为安全模式的话,参考官方文档
部署完获得后台网址就可以进行下一步:开始填写微信接口。其他的都随意填,关键的两个值是下图的箭头所指。

填好后会出现配置成功的标志。 这时就能在微信上使用这个公众号了。 本文所实现的功能是你向公众号发布一条信息,公众号返回同样的信息给你。

微信上最后结果

参考链接:

在Centos使用Nginx,uWSGI部署Flask应用

centos下通过gunicorn+nginx+supervisor部署Flask项目

nginx配置ssl加密

阿里云部署 Flask + WSGI + Nginx 详解

Gunicorn快速入门

微信公众号开发 flask后台的快速部署