默认使用Flask-RESTful==0.3.6框架,其他语言和框架仅供参考。

一、接口简介

实现在一个资源上实现手机号+密码+图形验证码登录手机号+短信验证码登录网页微信扫码登录IOS/Android客户端微信登录微信应用内网页登录

二、几点说明

  • 在用户登录前(即第一次访问服务器时),就应赋予用户一个临时的Token,可以用户验证码登录情形,亦可用于对非登录用户的行为追踪。
  • @decorate_source 的作用是:1、将返回值转化为 Json 字符串;2、拦截自定义异常并返回错误信息。实现:https://gist.github.com/bluicezhen/9f1b7a7f872c1d23fe643b178330d1fd
  • @decorate_body_params 的作用是验证获取 HTTP Body Params ,并将参数传递到 Flask.g 。实现:https://gist.github.com/bluicezhen/887060637386761f01da5fa85d2c76d2
  • 在用户未登录状态下,服务器会分配一个临时的AccessToken,放在返回值中,客户端需存储AccessToken并在任何请求时在HTTP Headers里面加入AccessToken。该参数用于:1、短信/图形验证码获取/登录;2、追踪未登录用户的使用行为。服务器需保证当前可用的AccessToken是唯一的。

三、几个重要的流程图

1、Sever 处理Token流程

注:kv存储中的key使用uuid5

三、数据库表定义(MySQL)

此处设计收到现有系统(榄盛金融)数据库结构的制约,仅做参考。此外本系统采用了分表策略,但该策略并不是在所有场景下均为最优,设计时需酌情考虑。

1. Table user

Field Type Null Key Default Extra Comment
uid int(11) unsigned No PRI null auto_increment
phone varchar(11) No UNI null
password varchar(32) No null hash

2. Table user_wx

Field Type Null Key Default Extra Comment
user_uid int(11) unsigned No PRI null auto_increment
union_id varchar(64) No IND null
openid_web varchar(64) Yes IND null 扫码登录

Foreign Key:

Column FK Table FK Column On Update On Delete
user_uid user uid CASCADE CASCADE

四、类定义

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
36
37
38
39
40
class ResourceUserAccessTokenList(Resource):
''' 资源:用户鉴权字符串列表 '''

@decorate_source()
@decorate_body_params(params_except=['login_method'])
def post():
login_method_list = {
"phone_password": self.post_login_by_phone_password,
"phone_message": self.post_login_by_phone_message,
"wx_qr": self.post_login_by_wx_qr
}

try:
return login_method_list[g.params["login_method"]]()
except KeyError:
raise HTTPException(400, '不支持或未实现的登录方式')

@decorate_body_params(params_except=['phone', 'password', 'captcha'])
def post_login_by_phone_password():
""" 手机号+密码+图形验证码登录 """
pass

@decorate_body_params(params_except=['phone', 'message_captcha'])
def post_login_by_phone_message():
""" 手机号+短信验证码登录 """
pass

@decorate_body_params(params_except=['code'])
def post_login_by_wx_qr():
""" PC端网页扫码登录

使用《网站应用微信登录开发指南》第二步,拿到openid实现登录逻辑即可
"""
pass

class ResourceImageCaptchaList():
""" 资源:图形验证码列表 """

def GET():
pass

五、请求案例

1、用户名+密码+图形验证码登录

request

1
2
3
4
GET /user_access_token HTTP/1.1
Host: exapmle.com
Content-Type: application/json

request

1
2
3
4
5
6
7
8
9
10
POST /user_access_token HTTP/1.1
Host: exapmle.com
Content-Type: application/json

{
"login_method": "phone_password",
"tmp_token": "34f1dc7c54e088b6164527dd00f2de0c"
"phone": "171xxxxxxxx",
"password": "123698745",
}

response

1
2
3
4
5
6
7
HTTP/1.1 200 OK
Content-Type: application/json
Date: Wed, 16 Aug 2017 10:31:00 GMT

{
"access_token": "8aeaa418da7ab54b4ea4348d126caeb7"
}