webapi适用场景

常见的应用包括以下四类,PC客户端程序,APP程序,网站程序,H5程序。
这些应用需要的数据,服务可由同一个接口服务程序提供,这样,大大提高了产品多平台设计开发的效率,避免了重复的编码。

什么是webapi

webapi一般采用restful风格。以tornado为例,url路由配置如下:

url = [
(r'/test', testfc.testHandler)
]

业务逻辑层,返回数据一般为json格式:

class testHandler(RequestHandler):
def get(self):
self.post()
def post(self):
result={}
if True:
result["code"]=""
result["status"]="true"
result["result"]="success"
else:
result["code"]=""
result["status"]="false"
result["result"]="fail"
self.write(json_encode(result))
return

webapi访问方式如下:

http://127.0.0.1:9999/test

返回结果:
{"status": "true", "code": "200", "result": "success"}

webapi架构设计

如何确认一个app能够访问webapi?
使用AppID验证app访问webapi的合法性,AppID为服务端给出的一个ID标志。
我们可以为web/app/winform分别分配一个ID,从而可以确定访问的合法性,和访问的渠道。

如何保证app参数的正确性,没有被篡改?
客户端使用AppID对应的AppSecert,对参数进行签名(MD5/SHA等)
服务端使用同样的方式签名,和客户端签名校验。

如何防止webapi url被截获,重新访问?
客户端访问webapi时带上时间戳参数,服务端对时间戳进行校验,如10分钟内的访问才是有效的。

涉及具体用户的操作时,如何验证用户?
可以使用username,psw参数的方式访问webapi。但是这种方式很不安全。
使用授权token是很好的解决办法。在用户登录成功时,服务端生成一个授权码,对应用户信息。
访问时带上token参数,服务端查询token有效性,和token对应的用户信息。

使用示例

签名代码如下:

#coding:utf-8

__author__ = 'jy'

import sys
reload(sys)
sys.setdefaultencoding('utf-8')
sys.path.append('..')
import datetime
import time
import math
import hashlib
import urllib
def md5encode(source):
m2 = hashlib.md5()
m2.update(source)
return m2.hexdigest()
def dataSort(data):
dataKeys=data.keys()
dataKeys.sort()
result=""
for key in dataKeys:
result+=key.strip()
result+=data[key].strip()
return result
def dataSecret(data):
secret="af4d2c92-4bb7-11e5-8111-00163e001071"
data=secret+data+secret
return data
def getSign(postdata):
try:
#升序排列,合并为字符串
dataSign=dataSort(postdata)
#加密钥
dataSign=dataSecret(dataSign)
#md5编码
dataSign=md5encode(dataSign)
return dataSign
except Exception as error:
pass

验证url参数代码如下:

#coding:utf-8
__author__ = 'haoy' import sys
reload(sys)
sys.setdefaultencoding('utf-8')
sys.path.append('..')
from tornado.escape import json_decode, json_encode
import datetime
import time
import math
from utils.sign import *
def valiUrldata(data):
result={}
try:
#判断appKey是否合法
appKey=data.get("appKey","")
if appKey!="21ec85ec-30ca-491b-8bfb-c05e479eadc0":
result["code"]=""
result["status"]="false"
result["result"]="账号不合法"
return result
#appKey对应的secret
appSecret="af4d2c92-4bb7-11e5-8111-00163e001071"
#检验时间
timeStamp=data.get("timeStamp","")
timeStamp=int(timeStamp)
nowtime=int(round(time.time())) if abs(timeStamp-nowtime)>600:
result["code"]=""
result["status"]="false"
result["result"]="请求时间戳不合法"
return result #校验签名
clientSign=data.get("sign","")
if clientSign=="":
result["code"]=""
result["status"]="false"
result["result"]="请求参数签名不能为空"
return result
data.pop("sign")
serverSign=getSign(data)
print serverSign
if clientSign!=serverSign:
result["code"]=""
result["status"]="false"
result["result"]="请求参数签名不合法"
return result
result["code"]=""
result["status"]="true"
result["result"]="通过验证"
return result
except Exception as error:
result["code"]=""
result["status"]="false"
result["result"]="异常:"+error.message
return result

登录代码如下:

import uuid
import redis
class testLoginHandler(BaseHandler):
def get(self):
self.post()
def post(self):
#获取url参数
args=self.request.arguments
data={}
for key in args:
data[key]=self.get_argument(key,"")
#验证url参数
valiResult=valiUrldata(data)
if valiResult["code"]=="":
self.write(json_encode(valiResult).decode("unicode_escape"))
return
username=self.get_argument("username","")
psw=self.get_argument("psw","")
if username=="shijingjing07" and psw=="":
token = uuid.uuid1()
redisPool = redis.ConnectionPool(host='127.0.0.1',password='', port=6379, db=0)
cache = redis.Redis(connection_pool=redisPool)
cache.setex(token,username,300)
result["code"] = 200
result["status"] = "true"
result["result"] = token
else:
result["code"] = 300
result["status"] = "false"
result["result"] = "account illegal"
self.write(json_encode(result))

返回结果:

{"status": "true", "code": 200, "result": "5720c334-dbcc-11e6-84f1-00163e001071"}
 

webapi应用架构详解的更多相关文章

  1. NopCommerce源码架构详解--初识高性能的开源商城系统cms

    很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从中学习很多企业系统.软件开发的规范和一些新的技术.技巧,可以快速地提高我们 ...

  2. 领域驱动设计(Domain Driven Design)参考架构详解

    摘要 本文将介绍领域驱动设计(Domain Driven Design)的官方参考架构,该架构分成了Interfaces.Applications和Domain三层以及包含各类基础设施的Infrast ...

  3. WeChatAPI 开源系统架构详解

    WeChatAPI 开源系统架构详解 如果使用WeChatAPI,它扮演着什么样的角色? 从图中我们可以看到主要分为3个部分: 1.业务系统 2.WeChatAPI: WeChatWebAPI,主要是 ...

  4. hdfs文件系统架构详解

    hdfs文件系统架构详解 官方hdfs分布式介绍 NameNode *Namenode负责文件系统的namespace以及客户端文件访问 *NameNode负责文件元数据操作,DataNode负责文件 ...

  5. NopCommerce源码架构详解

    NopCommerce源码架构详解--初识高性能的开源商城系统cms   很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从 ...

  6. RESTful 架构详解

    RESTful 架构详解 分类 编程技术 1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次 ...

  7. Nop--NopCommerce源码架构详解专题目录

    最近在研究外国优秀的ASP.NET mvc电子商务网站系统NopCommerce源码架构.这个系统无论是代码组织结构.思想及分层都值得我们学习.对于没有一定开发经验的人要完全搞懂这个源码还是有一定的难 ...

  8. Zookeeper系列二:分布式架构详解、分布式技术详解、分布式事务

    一.分布式架构详解 1.分布式发展历程 1.1 单点集中式 特点:App.DB.FileServer都部署在一台机器上.并且访问请求量较少 1.2  应用服务和数据服务拆分  特点:App.DB.Fi ...

  9. [转载]领域驱动设计(Domain Driven Design)参考架构详解

    摘要 本文将介绍领域驱动设计(Domain Driven Design)的官方参考架构,该架构分成了Interfaces.Applications和Domain三层以及包含各类基础设施的Infrast ...

随机推荐

  1. linux如何后台运行进程,而且不随终端关闭而关闭

    参考:http://www.cnblogs.com/kaituorensheng/p/3980334.html 使用命令nohup:no hang up,表示关闭终端后,进程并不随着终端关闭而关闭 f ...

  2. EF 不允许启动新事务,因为有其他线程正在该会话中运行。

    引起原因:在查询中提交了更改.如在遍历的时候,调用了savechanges(): 解决:把savechange()提到循环外.             IOrderedQueryable<TOH ...

  3. go语言基础之for循环

    1.for 的用法 示例: package main //必须有一个main包 import "fmt" func main() { //for 初始化条件 ; 判断条件 ; 条件 ...

  4. boost.asio学习笔记一、linux下boost库的安装

    欢迎转载,转载请注明原文地址:http://blog.csdn.net/majianfei1023/article/details/46761029 学习开源库第一步就是编译安装好库,然后执行成功一个 ...

  5. es修改索引副本个数

    es修改索引副本个数 PUT index01/_settings { "number_of_replicas": 2 }

  6. java中 this和super的差别

    this表示当前调用方法的对象的引用: (谁调用这种方法,谁就是这个对象,这个this就是它的引用) 比方: <pre name="code" class="jav ...

  7. Discuz常见小问题-如何删除用户

    用户-用户管理,直接拉到底部点搜索   切换到最后一页,然后勾选要删除的用户(最后一页就是最新注册的用户)   要勾选两个选项,删除过程比较长,不要中途退出,等待删除完毕   再次搜索用户就少一个了

  8. 利用反射实现JavaBean的自动赋值

    最近开发公司的一个项目,因项目不是很大的项目,所以仅仅采用了spring MVC框架,但是数据库很多表中的字段至少15个,这样当每次将数据库表中的数据取出来放入javabean中时,写setXXX方法 ...

  9. 取球游戏_nyoj_518(博弈-蓝桥杯原题).java

    取球游戏 时间限制: 1000 ms  |  内存限制: 65535 KB 难度: 2   描述 今盒子里有n个小球,A.B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下 ...

  10. 关于ActiveMQ的配置

    http://www.cnblogs.com/CopyPaster/archive/2012/04/27/2473179.html