web项⽬API接⼝设计与开发总结
当前公司⾃主开发的⼀个AI图⽚识别项⽬,需要对外开放提供接⼝,领导⼆话没说把这个任务交给我来做,算是对我的⼀次考验。虽然以前⾃⼰没有设计过接⼝,但是调⽤过别⼈写的接⼝,如百度提供的接⼝,还有以前在项⽬中调⽤别⼈的接⼝等等。感觉调⽤别⼈的接⼝还挺⽅便的,⾃⼰来设计的时候,真不知道如何下⼿。然后去查看学习各种教程,开始进⾏接⼝的设计与开发⼯作。
设计原则
鉴于⽬前的⽹络环境形式,设计的⾸要原则是安全第⼀原则,如果设计的接⼝不能保证其安全性,其他的活都相当于⽩⼲了。其次是简单原则,我认为调⽤接⼝的⽅式越简单越好,因为现在的⼈都很懒,这⼀点百度做得很好,调⽤他们的接⼝⾮常简单。如调⽤百度地图API,⼀个key就够了。⽬前只考虑到这两点,其他的还没有总结出来。
开发环境
Node.js + WebStorm + MySQL//说明:公司选择JavaScript作为后台开发的主要语⾔,开发难度估计只有Java的⼀半,可是现在使⽤的公司却⾮常少,搞不懂为什么。据统计NPM上⾯包的下载量和MAVEN的包下载量不是⼀个量级的,使⽤NPM的⼈超多,⽐⽤MAVEN的⼈多多了。
整体设计
这个接⼝的最终成型不是⼀下⼦全部就实现了,⽽是在⼯作中不断地改进,在每次改动中不断地变得越来越好,才算完成⼀个初步的版本。写代码就好⽐谈恋爱,两个⼈不可能⼀下⼦熟悉起来,⽴刻热恋,然后马上结婚,特例除外。在开发的过程中需要⼀直不停的更改,即使是上线了也有可能还需要修改,没有最终版本,因为需求的变动是不确定的。
这个接⼝是于⼀个独⽴的项⽬,为了在部署时⽅便,也为了调⽤时不和正式项⽬发⽣冲突,所以单独进⾏开发。所有的请求分为两⼤类,⼀类是获取⽤户token的请求,⼀类是进⾏业务操作的请求。
请求处理的先后顺序:请求--->获取⽤户token---->其他业务操作。如下图:
开发过接⼝的⼈都知道,⼀般来说接⼝是没有页⾯的,只有后台;并且出于安全起见,所有的请求全部为POST请求。按照上⾯的设计来进⾏开发,获取⽤户token的请求不会被拦截,这步操作有些类似于⽤户登录的操作。其他的业务操作全部需要先经过先处理,验证通过后才放⾏,验证不通过则返回错误信息。
获取⽤户token时,需要传递三个参数,⽤户名、⽤户密码和⼀个秘钥key(UUID⽣成),其中⽤户密码和秘钥key都使⽤MD5加密。MD5加密不可逆,为了防⽌敏感信息被别⼈窃取,所以采取加密传输。验证通过则返回⽤户token和私钥,有效时间都是⼀个⼩时。秘钥key没有采⽤特殊的⽣成规则,⽐如⽤户ID+⽇期+项⽬名称+随机数字。使⽤简单的UUID⽣成32位长度的随机字符,我觉得很low,可是破解的概率极⼩,既简单⼜安全还实⽤。
返回的状态码和消息只有三种:接⼝调⽤失败,业务操作成功,业务操作失败。最开始设计时还加了⼀种接⼝调⽤成功,可后来转念⼀想,这⼀步有些多余。如果接⼝调⽤成功,那⼀定会进⾏业务操作,剩下的则是业务操作的事情了,所以把接⼝调⽤成功这⼀状态取消了。
所有操作分为三种情况:
接⼝调⽤失败---->返回错误信息;
业务操作成功--->返回操作成功信息;
业务操作失败---->返回业务操作失败信息。
设计实现。⽤来拦截业务操作的所有请求,进⾏安全验证。验证的主要内容有:请求IP地址验证---->⽤户token验证---
百度api接口>rsa签名验证--->秘钥key验证。只有全部通过验证后才放⾏,否则返回错误信息。如果不清楚rsa加密⽅式的朋友可以先去百度百科⾥⾯了解⼀下rsa加密⽅式。
⾄于业务操作的设计则没有什么特别之处,和平常的增、删、改、查差不多。写⼀点,关于参数处理,如果可以的话,最好要在后台进⾏参数校验,我坚信⼀点,永远不要相信⽤户会按照你设计的⽅式来进⾏操作。所以对于⽤户输⼊的所有参数⾃⼰会严格验证,验证通过后才让程度进⾏下⼀步操作。
接⼝测试
由于接⼝没有页⾯,测试时不像⼀般的页⾯那样⽅便,只能采取其他⽅式来进⾏测试。同事建议我使⽤⾕歌的⼀个专业测试软件Postman,⾃⼰使⽤后觉得还将就,不过我认为还是不太⽅便。然后换⽤了另
外⼀种本⼈认为更简单的⽅式,使⽤WebStorm 创建⼀个新项⽬,只需要导⼊可以发送POST请求的包即可,然后⼀个test.js⽂件搞定所有测试。
秘钥key使⽤rsa(私钥)加密,token原样传输,参数使⽤aes加密,然后在在使⽤rsa(私钥)进⾏签名操作⽣成签名字符串。签名主要是为了防⽌数据在传输过程中被串改,敏感数据则使⽤rsa私钥加密,然后⽤公钥解密,也可以使⽤公钥加密,私钥解密,主要是为了防⽌被窃取。但是我了解到的是rsa签名只能使⽤私钥,再使⽤公钥验证签名。
⾃⼰创建⼀个新项⽬来进⾏测试,⼀个接⼝接着⼀个接⼝的测试,很快全部测试完毕,Word⽂档也同步写好。测试⼯作完成则表明接⼝开发的初步版本完成。
遇到的问题
开发和测试中肯定会遇到各种各样的问题,在此只写⼏个有代表性的问题。
第⼀个问题,rsa加密有长度限制,⽹上说只能加密117个字节,当我加密的数据太长时果然出现问题,⽐如加密Base64格式的图⽚信息出问题。为了解决这个问题,所以使⽤aes来进⾏加密和解密数据,图⽚信息也不受影响。
第⼆个问题,使⽤rsa加密的数据中可能会含有加号,开始时我是放在URL中进⾏传输,之后在解析时会将加号解析为空格,这个问题是采了很久的坑才知道的。左思右想才想到⼀个很好的解决办法是在解析URL参数后,使⽤正则表达式将字符串中的空格全部替换为加号,测试完全可⾏。
这种⽅式对于有单个加号的数据可⾏,可是后⾯测试时,问题来了。⼀次数据验证签名⼀直没有通过,我很奇怪,刚才还好好的,怎么⼀下⼦就不⾏了呢。仔细查原因才知道,在使⽤rsa进⾏数据签名操作时,字符串中出现了三个连续加号如下:
FayA44XDO5jeqDbafkMqzogMZHvJ+l3CX3myjiPYrsyyXV7KJvgjgNeVf+++m/UDNrcTuFQ2DnzR+rngygfJ0Q==
这是我意识到问题的严重性,rsa操作⽣成的数据最好不要拼接在url中传输,否则会出问题。如果⼀定要拼接在URL中进⾏传输,则对加号⼀定要特殊处理。我的处理⽅式是所有参数全部放在body中进⾏传输,这样解析时就不会出问题。
第三个问题,数据在传输前是JavaScript中的⼀个对象,不便于传输,为了解决这个问题尝试过不少⽅法,最终决定采⽤
JSON.stringify()//JSON.parse()这⼀对函数来解决。因为数据加密只能加密字符串,可以使⽤JSON.stringify()函数将JSON对象转换为字符串,然后进⾏加密传输。对字符串进⾏解密后在使⽤JSON.parse()函数将字符串转换为JSON对象。测试可⾏,圆满解决这个问题。
第四个问题,获取token的请求和其他⼤的业务请求操作不太⼀样,在中我做了⼀次请求地址的判断,如果请求地址是获取token则直接跳转到对应的⽅法,否则放⾏进⾏其他业务操作。这样做虽然每⼀次都需要做⼀次请求判断,可是代码量⼤⼤滴减少了,因为每⼀个请求都需要做IP地址验证,如果不这样处理,则需要把请求地址验证的⽅法单独写到⼀个⽂件中,放在最前⾯,我没有这样做,感觉这样做⽐较⿇烦,还是使⽤⼀个⽅便、简单些。
总结
从这次设计、开发、测试接⼝中学到不少的东西,虽然这个接⼝项⽬还在不断地完善,不过我知道我肯定会做得越来越好。⽐如关于安全⽅⾯,后期肯定还会添加验证,⽤于防⽌攻击,如防⽌频繁的请求攻击,只限制post请求进⼊等等。
真实的项⽬开发中学习到的这些东西印象都会⾮常深刻,不容易忘记。⾃⼰平时也在学习其他的编程语⾔⽐如Python,学习完后没有使⽤起来会很快忘记。在⼯作中则不⼀样,可以做到真正的学以致⽤,学习到的东西需要马上使⽤,这时印象会⾮常的深刻。
学到⽼,活到⽼是我⼀贯坚持的信条,写这篇博⽂分享出来也算是对⾃⼰⼯作的⼀种总结,⼀种学习。如果各位开发的朋友有不懂的或者是有更好建议,欢迎留⾔。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论