webapi应用架构详解
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应用架构详解的更多相关文章
- NopCommerce源码架构详解--初识高性能的开源商城系统cms
很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从中学习很多企业系统.软件开发的规范和一些新的技术.技巧,可以快速地提高我们 ...
- 领域驱动设计(Domain Driven Design)参考架构详解
摘要 本文将介绍领域驱动设计(Domain Driven Design)的官方参考架构,该架构分成了Interfaces.Applications和Domain三层以及包含各类基础设施的Infrast ...
- WeChatAPI 开源系统架构详解
WeChatAPI 开源系统架构详解 如果使用WeChatAPI,它扮演着什么样的角色? 从图中我们可以看到主要分为3个部分: 1.业务系统 2.WeChatAPI: WeChatWebAPI,主要是 ...
- hdfs文件系统架构详解
hdfs文件系统架构详解 官方hdfs分布式介绍 NameNode *Namenode负责文件系统的namespace以及客户端文件访问 *NameNode负责文件元数据操作,DataNode负责文件 ...
- NopCommerce源码架构详解
NopCommerce源码架构详解--初识高性能的开源商城系统cms 很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从 ...
- RESTful 架构详解
RESTful 架构详解 分类 编程技术 1. 什么是REST REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态转移. 它首次 ...
- Nop--NopCommerce源码架构详解专题目录
最近在研究外国优秀的ASP.NET mvc电子商务网站系统NopCommerce源码架构.这个系统无论是代码组织结构.思想及分层都值得我们学习.对于没有一定开发经验的人要完全搞懂这个源码还是有一定的难 ...
- Zookeeper系列二:分布式架构详解、分布式技术详解、分布式事务
一.分布式架构详解 1.分布式发展历程 1.1 单点集中式 特点:App.DB.FileServer都部署在一台机器上.并且访问请求量较少 1.2 应用服务和数据服务拆分 特点:App.DB.Fi ...
- [转载]领域驱动设计(Domain Driven Design)参考架构详解
摘要 本文将介绍领域驱动设计(Domain Driven Design)的官方参考架构,该架构分成了Interfaces.Applications和Domain三层以及包含各类基础设施的Infrast ...
随机推荐
- JMS基本概念之二
JMS规范 JMS定义了Java中访问消息中间件的接口,并没有给予实现,实现JMS接口的消息中间件称为JMS Provider,例如ActiveMQ JMS provider: 实现JMS接口和规范 ...
- django 实现上传文件功能
需求:自己写一个文件上传功能 代码: urls.py from django.conf.urls import url from django.contrib import admin from ap ...
- java学习笔记10--泛型总结
java学习笔记系列: java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 java学习笔记6--类的继承.Object类 java学习笔记5-- ...
- List、Set、Map、数组之间各种转换
刚学Java不久的时候,接到一个电面,然后问了一些java的知识,比如说Java的编码,Unicode等,但是最让我蛋疼的是怎么吗map转为set,那个时候对集合用的很少,对集合不是特别了解,map还 ...
- Qt正则表达式提取数据
这几天在上嵌入式课程设计,需要用到Qt,这个是信号与槽的,寒假的时候也简单学习了一些,但是没有怎么深入,又回过来看了看Qt,发现Qt的ui界面配置与Android的好像,当然Qt也可以拿来开发Andr ...
- DG日志不应用,GAP,主备切换解决思路与办法
环境ORACLE 10G OS WINDOWS 对于DG故障解决思路,DG日志切换不进行应用,DG出现GAP解决方法,DG主备库切换, 当DG出现故障时,第一时间检测alert日志,服务器OS日志,网 ...
- 使用ReportStudio打开cube模型创建报表出现两个最细粒度名称
本人也是第一次遇到这样的问题,此问题甚是简单,也许很简短的一句话就可以解决这个问题了,看官请留神哦 cube做好发布到cognos之后使用Analysis Studio打开结构正常 于是想到要用此数据 ...
- gsoap
C++中如何使用gsoap开发WebService 1. 什么是gSOAPgSOAP是一个夸平台的,用于开发Web Service服务端和客户端的工具,在Windows.Linux.MAC OS和UN ...
- 桥(Bridge)模式
Bridge定义:将抽象和行为划分开来,各自独立,但能动态的结合. 为什么使用桥模式 通常,当一个抽象类或接口有多个具体实现(concrete subclass),这些concrete之间关系可能有以 ...
- ant design pro (十一)advanced Mock 和联调
一.概述 原文地址:https://pro.ant.design/docs/mock-api-cn Mock 数据是前端开发过程中必不可少的一环,是分离前后端开发的关键链路.通过预先跟服务器端约定好的 ...