移动端后台开发 (加密验证--通用接口篇)
前言
在 Web 开发中浏览器与服务器进行通讯,在服务器端我们可以用 "session" 来确定用户的身份,然后根据从浏览器接收到的参数,服务器返回给浏览器相应的数据。但是在移动端与服务器进行通讯时,并没有 "session" 的存在 (也许是我不知道), 不过我们可以要求移动端提交参数的时候把用户的 "id" 或 "Guid" 和其他参数一起提交过来。然后根据请求的参数来返回对应的内容.
那么问题来了,我可以使用抓包工具获取别人提交 "url 地址" 与 "参数",然后进行模拟操作,我就可以获取该用户的全部数据,如果涉及到金钱的话,更是一场毁灭性的灾难。所以,在开始一个移动端的项目前,加密验证是最先考虑与准备的事情.
毕竟谁也不希望,有人可以在自己家里面随意的进进出出!
一、接口分类
在我们日常接触的 app 中,像 "登录","注册","找回密码" 这种没有登录的情况下,都可以访问的接口,我们称为 "通用接口", 像 "个人信息","支付密码", 这种涉及到个人隐私或者金钱的接口,我们称为 "非通用接口", 再次重复一下,接口分为
1. 通用接口 // 加密程度略低于非通用接口,但必须要做加密
2. 非通用接口 // 必须是你知道的最安全的加密方式
附上代码
private static $verify;
// Verify 为注入文件
public function __construct(Verify $verify)
{
self::$verify = $verify;
}
private function verify($request)
{
if($request->path()=='login'){
// 通用方法
return self::$verify->common($request);
}else{
// 非通用方法
return self::$verify->proprietary($request);
}
return false;
}
public function handle($request, Closure $next)
{
$time = time();
// 此处调用上边的verify方法,根据返回的状态码,来返回移动端信息提示
switch($this->verify($request))
{
case "SN200":
$temp = $next($request);
return $temp;
break;
//最后在完善其他状态码信息
}
}
下面我们看看访问 login 路由时,通用方法都做了什么?
public function common($request)
{
// 接收request对象
if($request->all()){
$data = $request->all();
// 时间验证
// $data['time']为移动端当前时间戳
$ckTime = $this->checkTime($data['time']);
// SN002 请求超时
if(!$ckTime) return 'SN002';
// 验证ID的存在
// SN004 用户没有登录
if(!isset($data['id'])) return 'SN004';
// 根据移动端传递的版本号来进行加密验证
switch ($data['version']){
case $data['version'] >'1.4' && $data['version']<'2.0':
// 开始进行通用加密验证
$temp = $this->checkCommon_v1($request);
break;
default:
$temp = $this->checkCommon_v2($request);
break;
}
if($temp){
// SN200 验证通过
return "SN200";
}
// SN005 签名错误
return "SN005";
}
// 服务器有请求,但参数为空,通常与安卓和ios的框架有关系(需注意)
return false;
}
代码与注解:
-
时间验证
public function checkTime($time) { $Time_difference = abs(time()-$time); if($Time_difference>30){ return false; } return true; }
请求到达服务器的时间减去移动端本地的时间戳,如果大于
30
秒,就代表请求超时,有可能是该用户的网络不算太好。如果不使用abs()
函数的话,万一我的数据包被别人抓住了他可以无限大的修改$time
这个值,那么使用服务器时间戳去相减的到的一直是负数,还是小于30
秒的。由此可见使用abs()
函数会更加的安全一些。 -
验证
ID
的存在
主要是为接下来的非通用接口验证做准备。通用接口的
ID
可以与移动端事前定义一个值。"移动端与服务端 ID 的值一定要相同,要不然没办法做接下来的验证"
- 根据移动端传递的版本号来进行加密验证
每个大版本的改变,加密的方式都应随着改变而改变。小版本的修正就没有必要去更换加密方式了。
-
通用加密验证
private function checkCommon_v1($request) { $data = $request->all(); $path = $request->path(); $time = $data['time']; $id = '1'; $param = $data['param']; $cryptToken = "JRzhang"; $signature = md5($path.$time.$id.$param.$cryptToken); if($signature!=$data['signatures']){ return false; }else{ return true; } }
这里说一下移动端应传递的参数
time 移动端当前时间
param 真正的请求参数 数组转为 json 后的字符串
version 移动端当前版本
deviceid 设备唯一识别码 (非通用接口使用,用于单点登录)
signature 签名移动端应按照上边的参数顺序进行 MD5 加密
cryptToken 移动端保存一份与服务器端相同,但不进行参数传递只做加密使用
坑点:服务器对 android
进行接口调试时,一定要注意 android
本地的时间戳。因为 android
手机可以 tmd
调整本地时间.
最后如果移动端传递的 signature
与服务器端生成的 $signature
相同,那么恭喜你,你可以从我家的大门进来了,但只可以在院子里转一转,如果想进屋里,请继续关注
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: