你在写开放的API接口时是如何保证数据的安全性的?先来看看有哪些安全性问题在开放的api接口中,我们通过http Post或者Get方式请求服务器的时候,会面临着许多的安全性问题。
例如:
请求来源和身份是否合法?
请求参数被篡改?

为了保证数据在通信时的安全性,我们可以采用MD5+RSA参数签名的方式来进行相关验证。
依赖js文件:http://www.fores.cc/usr/uploads/2017/08/383667649.zip

前端生成签名


<button id='ajax'>ajax</button>
<div id='text'></div>
<script type="text/javascript">

/*
 * 生成签名
 * @params  待签名的json数据
 * @secret  密钥字符串
 */
function makeSign(params, secret){
    var ksort = Object.keys(params).sort();
    var str = '';
    for(var ki in ksort){ 
    str += ksort[ki] + '=' + params[ksort[ki]] + '&'; 
    }

    str += 'secret=' + secret;
    var token = hex_md5(str).toUpperCase();
    return rsa_sign(token);
}

/*
 * rsa加密token
 */
function rsa_sign(token){
     var pubkey='-----BEGIN PUBLIC KEY-----';
    pubkey+='MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAbfx4VggVVpcfCjzQ+nEiJ2DL';
    pubkey+='nRg3e2QdDf/m/qMvtqXi4xhwvbpHfaX46CzQznU8l9NJtF28pTSZSKnE/791MJfV';
    pubkey+='nucVcJcxRAEcpPprb8X3hfdxKEEYjOPAuVseewmO5cM+x7zi9FWbZ89uOp5sxjMn';
    pubkey+='lVjDaIczKTRx+7vn2wIDAQAB';
    pubkey+='-----END PUBLIC KEY-----';
    // 利用公钥加密
    var encrypt = new JSEncrypt();
    encrypt.setPublicKey(pubkey);
    return encrypt.encrypt(token);
}

/*
 * 获取时间戳
 */
function get_time(){
    var d = new Date();
    var time = d.getTime()/1000;
    return parseInt(time);
}

//secret密钥
var secret = 'e10adc3949ba59abbe56e057f20f883e';

$("body").on("click","#ajax",function(){
    var params = {};
    params.name = 'zhansan';
    params.age = '30';
    params.timestamp = get_time();
    params.sign = makeSign(params, secret);
    $.ajax({
        url : "http://localhost/index1.php",
        data : params,
        type:'post',
        success:function(msg){
            $('#text').html(msg);
        },
        async:false
    })
})
</script>

php端校验


<?php

//rsa 私钥
$private_key='-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDAbfx4VggVVpcfCjzQ+nEiJ2DLnRg3e2QdDf/m/qMvtqXi4xhw
vbpHfaX46CzQznU8l9NJtF28pTSZSKnE/791MJfVnucVcJcxRAEcpPprb8X3hfdx
KEEYjOPAuVseewmO5cM+x7zi9FWbZ89uOp5sxjMnlVjDaIczKTRx+7vn2wIDAQAB
AoGAZzUWajxKTZeJqh5FjBgmwZi5M7voFynZAjRWAkCkqZye0FfY7e70kA92C1AL
aVqySnNr4WYZuGorEeOFGqHIv1XSowTLgfLkVBZ/SXiep2QYJrR0YevjysvLnTfb
mrdWCqWSj+0AlQg+AvDA/qtvBVMxKymbpo+4bj5H2pPPZ1ECQQDi1PwJQJBYPbpL
vGmP3AmWg467tCeQ+aJGgtQTOK5BH+p0BWFVDX583R437vllkKI8EXgZfqQfsQcj
7XUAXyZVAkEA2SyFbO8roH9JLrEoxxKGeiGZvhPfNl9nXLhX0OFS0ywQaVBJno39
9W5bX5iP5Jzeb3UWsZ/TxzhGc/b4WjAlbwJBAOFuIn1feRT5Y+hY++BJIg4/+N57
EMd4ENpas0HXFvcKLQvZPP42Rvr5FksoaRuTPmjMQ7uyrJICccI3AAy6g3ECQQDE
AyH9+zRmLNxRj0advsOvUcpgu7DYc21oS12/Qs+tl3TMiNGZkNDphwxjkOA217sP
4B92fCn6AnncSslHJXNzAkBo6ujxqIfrZMOG3ON9nXxkWlq39GFS6CzXWscHA3Xz
FMVT1WWU3FR2Kf2QSKiMGv02YcI2xfowim3JnT6600N0
-----END RSA PRIVATE KEY-----';

//secret密钥
$secret = 'e10adc3949ba59abbe56e057f20f883e';

//私钥解密获取token
openssl_private_decrypt(base64_decode($_POST['sign']), $token, $private_key); 

if($token != MakeSign($_POST, $secret)){
    exit('token校验失败') ;
}else{
    exit('token校验成功');
}

echo date('Y-m-d H:i:s', $_POST['timestamp']);//timestamp参数可以用来验证接口请求时间的有效性



 /**
 * 生成签名
 * 备注:sign不参与签名
 * $data # 数组
 * $secret # 密钥
 */
function MakeSign($data = '', $secret = '')
{
    //签名步骤一:按字典序排序参数
    ksort($data);
    //签名步骤二:格式化成url参数
    $buff = "";
    foreach ($data as $k => $v)
    {
        if($k != "sign"){
            $buff .= $k . "=" . $v . "&";
        }
    }
    $string = trim($buff, "&");
    //签名步骤三:在string后加入KEY
    $string = $string . "&secret=".$secret;
    //签名步骤四:MD5加密
    $string = md5($string);
    //签名步骤五:所有字符转为大写
    $result = strtoupper($string);
    return $result;
}