Sign签名和token⼝令
Sign签名⽣成与校验
⼤家先思考⼀个问题: 你在写开放的API接⼝时是如何保证数据的安全性的?
先来看看有哪些安全性问题在开放的api接⼝中,我们通过http Post或者Get⽅式请求服务器的时候,会⾯临着许多的安全性问题,例如:
1. 请求来源(⾝份)是否合法?
2. 请求参数被篡改?
3. 请求的唯⼀性(不可复制)
签名字符串是什么
解决⽅案:为了保证数据在通信时的安全性,我们可以采⽤参数签名的⽅式来进⾏相关验证。
案列分析
我们通过给某 [移动端(app)] 写 [后台接⼝(api)] 的案例进⾏分析:
客户端:以下简称app
后台接⼝:以下简称api
我们通过app查询产品列表这个操作来进⾏分析:
app中点击查询按钮》调⽤api进⾏查询》返回查询结果==>显⽰在app中
⼀、不进⾏验证的⽅式
api查询接⼝:
如上,这种⽅式简单粗暴,通过调⽤getproducts⽅法即可获取产品列表信息了,但是这样的⽅式会存在很严重的安全性问题,没有进⾏任何的验证,⼤家都可以通过这个⽅法获取到产品列表,导致产品信息泄露。
那么,如何验证调⽤者⾝份呢?如何防⽌参数被篡改呢?
⼆、MD5参数签名的⽅式
我们对api查询产品接⼝进⾏优化:
1.给app分配对应的key、secret
2.Sign签名,调⽤API 时需要对请求参数进⾏签名验证,签名⽅式如下:
a. 按照请求参数名称将所有请求参数按照字母先后顺序排序得到:keyvalue 字符串如:将arong=1,mrong=2,crong=3 排序为:arong=1, crong=3,mrong=2 然后将参数名和参数值进⾏拼接得到参数字符串:arong1crong3mrong2。
b. 将secret加在参数字符串的头部后进⾏MD5加密 ,加密后的字符串需⼤写。即得到签名Sign
新api接⼝代码:
注:secret 仅作加密使⽤, 为了保证数据安全请不要在请求参数中使⽤。
如上,优化后的请求多了key和sign参数,这样请求的时候就需要合法的key和正确签名sign才可以获取产品数据。这样就解决了⾝份验证和防⽌参数篡改问题,如果请求参数被⼈拿⾛,没事,他们永远也拿不到secret,因为secret是不传递的。再也⽆法伪造合法的请求。
但是...这样就够了吗?细⼼的同学可能会发现,如果我获取了你完整的链接,⼀直使⽤你的key和sign和⼀样的参数不就可以正常获取数据了...-_-!是的,仅仅是如上的优化是不够的。。。。。。
请求的唯⼀性:
为了防⽌别⼈重复使⽤请求参数问题,我们需要保证请求的唯⼀性,就是对应请求只能使⽤⼀次,这样就算别⼈拿⾛了请求的完整链接也是⽆效的。
唯⼀性的实现:在如上的请求参数中,我们加⼊时间戳:timestamp(yyyyMMddHHmmss),同样,时间戳作为请求参数之⼀,也加⼊sign算法中进⾏加密。
新的api接⼝:
Sign签名安全性分析:
通过上⾯的案例,我们可以看出,安全的关键在于参与签名的secret,整个过程中secret是不参与通信的,所以只要保证secret不泄露,请求就不会被伪造。
总结
上述的Sign签名的⽅式能够在⼀定程度上防⽌信息被篡改和伪造,保障通信的安全,这⾥使⽤的是MD5进⾏加密,当然实际使⽤中⼤家可以根据实际需求进⾏⾃定义签名算法,⽐如:RSA,SHA等加密算法。
1:sign验证法:
这种验证⽅式,⼀般过程是:
第⼀:给你⼀个【私钥】[app_secret] 和[app_id]
第⼆:你要提交的所有数据都需要提供sign签名。
第三:sign签名的获取⽅式。
例如:给⽤户id为99的⼈增加100积分:
$app_id = 'Te001';
$secret = 'e10adc3949ba59abbe56e057f20f883e';
$url = '127.0.0.1/test/apiDataCheck';
$post = array(
'user_id' => 99,
'point' => 100
)
;
function addSign($url, $data){
$str = '';
$data['app_id'] = $app_id;
ksort($data);
foreach($data as $k => $v){
$str .= $k.'='.$v.'&';
}
$str = substring($str, 0, -1);
$str = $url.'?'.$str.$secret;
$data['sign'] = md5($str);
return $data;
}
curl_post($url, addSign($post));
addSign 就是⼀个sign的获取⽅式:所有数据加上app_id,字段顺序排序,以get参数⽅式连接。然后url+?+get参数+私钥,进⾏md5加密获取sign签名。进⽽进⾏接⼝调⽤。
第四:服务器端验证数据合法性。
接⼝在操作数据之前,⾸先按照原本既定的sign⽣成⽅式,验证sign合法性,进⽽进⾏下⼀步操作。
sign⽣成的两种⽅式:
在前端直接⽤密钥⽣成sign,后端⽤相同的密钥验证。
前端先将需要请求的参数调⽤⼀个api接⼝,后端⽣成sign传给前端,前端再拿sign加参数区请求后端,后端再⽤之间api接⼝⽣成的sign验证。
2:token法:
token法的步骤⼤概是:
1:给你⼀个app_id和app_secret。
2:提供⼀个利⽤app_id和app_secret获取token的接⼝。
3:token的时效性设定。
4:获取token接⼝的使⽤次数限制。
1:获取token
$app_id = 'Token001';
$app_secret = 'e10adc3949ba59abbe56e057f20f883e';
$url = '127.0.0.1/token/getToken?app_id='.$app_ip.'&app_secret='.$app_secret;
$token = curl_get($url);
// $token = array(
/
/    'token' => 'e10adc3949ba59abbe56e057f20f883e',
//    'expire' => '1444444400'
// );
session('token', $token['token']);
session('expire', $token['expire']);
2:接⼝调⽤
$url = '127.0.0.1/token/getUserInfo';
$post['user_id'] = 1;
if(time() < session('expire')){
$post['user_id'] = 1;
$post['token'] = session('token');
}else{
步骤1:
}
$userInfo = curl_post($post);
5:服务器验证token:
Token原理以及应⽤
⼀、token的优势
1.⽆状态、可扩展
在客户端存储的Tokens是⽆状态的,并且能够被扩展。基于这种⽆状态和不存储Session信息,负载负载均衡器能够将⽤户信息从⼀个服务传到其他服务器上。
如果我们将已验证的⽤户的信息保存在Session中,则每次请求都需要⽤户向已验证的服务器发送验证信息(称为Session亲和性)。⽤户量⼤时,可能会造成⼀些拥堵。但是不要着急。使⽤tokens之后这些问
题都迎刃⽽解,因为tokens⾃⼰hold住了⽤户的验证信息。
2.安全性
请求中发送token⽽不再是发送cookie能够防⽌CSRF(跨站请求伪造)。即使在客户端使⽤cookie存储token,cookie也仅仅是⼀个存储机制⽽不是⽤于认证。不将信息存储在Session中,让我们少了对session操作。
token是有时效的,⼀段时间之后⽤户需要重新验证。我们也不⼀定需要等到token⾃动失效,token有撤回的操作,通过token revocataion可以使⼀个特定的token或是⼀组有相同认证的token⽆效。
3.可扩展性
Tokens能够创建与其它程序共享权限的程序。例如,能将⼀个随便的社交帐号和⾃⼰的⼤号(Fackbook或是Twitter)联系起来。当通过服务登录Twitter(我们将这个过程Buffer)时,我们可以将这些Buffer附到Twitter的数据流上(we are allowing Buffer to post to our Twitter stream)。
使⽤tokens时,可以提供可选的权限给第三⽅应⽤程序。当⽤户想让另⼀个应⽤程序访问它们的数据,我们可以通过建⽴⾃⼰的API,得出特殊权限的tokens。
4.多平台跨域
我们提前先来谈论⼀下CORS(跨域资源共享),对应⽤程序和服务进⾏扩展的时候,需要介⼊各种各种的设备和应⽤程序。
Having our API just serve data, we can also make the design choice to serve assets from a CDN. This eliminates the issues that CORS brings up after we set a quick header configuration for our application.
只要⽤户有⼀个通过了验证的token,数据和资源就能够在任何域上被请求到。
Access-Control-Allow-Origin: *
5.基于标准
创建token的时候,你可以设定⼀些选项。我们在后续的⽂章中会进⾏更加详尽的描述,但是标准的⽤法会在JSON Web Tokens体现。
最近的程序和⽂档是供给JSON Web Tokens的。它⽀持众多的语⾔。这意味在未来的使⽤中你可以真正的转换你的认证机制。
⼆、Token的原理
1.将荷载payload,以及Header信息进⾏Base64加密,形成密⽂payload密⽂,header密⽂。
2.将形成的密⽂⽤句号链接起来,⽤服务端秘钥进⾏HS256加密,⽣成签名.
3.将前⾯的两个密⽂后⾯⽤句号链接签名形成最终的token返回给服务端
注:
(1)⽤户请求时携带此token(分为三部分,header密⽂,payload密⽂,签名)到服务端,服务端解析第⼀部分(header密⽂),⽤Base64解密,可以知道⽤了什么算法进⾏签名,此处解析发现是HS256。
(2)服务端使⽤原来的秘钥与密⽂(header密⽂+"."+payload密⽂)同样进⾏HS256运算,然后⽤⽣成的签名与token携带的签名进⾏对⽐,若⼀致说明token合法,不⼀致说明原⽂被修改。
(3)判断是否过期,客户端通过⽤Base64解密第⼆部分(payload密⽂),可以知道荷载中授权时间,以及有效期。通过这个与当前时间
对⽐发现token是否过期。
三,实现思路
1.⽤户登录校验,校验成功后就返回Token给客户端。
2.客户端收到数据后保存在客户端
3.客户端每次访问API是携带Token到服务器端。
4.服务器端采⽤filter过滤器校验。校验成功则返回请求数据,校验失败则返回错误码

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。