Security php interface to achieve?

https://www.cnblogs.com/afsj/p/7424320.html
when doing PHP APP interfaces, how to ensure the security interface?

1, when the user logs APP, use the https protocol to call back the relevant interface, the server generates a access_key according to the user name and password and access_key stored in the session, and the resulting access_key session_id return to the APP end.

2, APP access_key end received and saved session_id

3, when the interface data transfer calls APP terminal, the transmitted data and the signature access_key signature is generated using an encryption algorithm, and a signature session_id and transmitted together to the server.

4, when the server receives data, corresponding to obtain from the session using session_id in access_key, access_key and the received data using the same encryption algorithm to generate the corresponding signature, if the generated signature and the received signature is the same, it indicates that the data is valid

https://www.cnblogs.com/zouke1220/p/9394356.html
PHP Interface Design of Security
Token authorization mechanism
timestamp timeout mechanism:
signature mechanism:
rejected repeated calls: when a client first visit, will sign signature store to the cache server, the timeout is set to coincide with the time-out time stamp, can guarantee the same time both in terms of the time limit within or outside the timestamp URL can only be accessed once.
Illegal ip access restrictions, restrictions here are generally used in the interface between the server's call to do this limit whitelist
https access

Security around the main interface Token, Timestamp and Sign launched three mechanisms designed to ensure data interface will not be tampered with and called repeatedly, the following specific point of view:

(1) Token authorization mechanisms: (Token is the Client Access server credentials) - User user name password to log the server to the client returns a Token (usually a UUID), and Token-UserId form of key-value pairs stored in the cache server. Token validation services were terminated after receipt of the request, if there is no Token, indicating that the request was invalid.

(2) :( timeout mechanism stamp signature mechanism to ensure the data is not tampered with) each time a user request is put on the timestamp of the current time timestamp, followed by the server receives the current time timestamp for comparison, if the time difference is greater than a predetermined time (such as 5 minutes), the request is considered invalid. Timestamp timeout mechanism is an effective means of defense DOS attacks.

(3) signature mechanism: The Token request parameters and timestamp plus other then MD5 or SHA-1 algorithm (salt can be added according to the situation) encryption, data is encrypted signature Sign this request, the service receives a request after the signature of the same algorithm, and to compare with the current signature, if not the same, indicating that the parameter is changed, an error is returned directly identify.
Copy the code

/**

  • @desc accepts parameter processing
    * /
    Private dealParam function () {
    // Parameters header accepts - system parameter
    $ systemParam getAllHeadersParam = ();
    // data receiving body - service parameters (JSON format)
    $ Data = file_get_contents ( 'PHP: // input ');

    // private key information to read the configuration file
    $ api_apiKey = C ( 'api_apiKey');
    $ $ api_apiKey PrivateKey = [$ systemParam [ 'token']];

    $ arr [ 'token'] = $ systemParam [ 'token']; // server assigned identifier (different clients need to use different identification)
    $ ARR [ 'timestamp'] = $ systemParam [ 'timestamp']; / / time stamp, UTC time zone to GMT East (+8) eight prevail
    $ arr [ 'version'] = $ systemParam [ 'version']; // version number
    $ arr [ 'sign'] = $ systemParam [ 'sign']; // signature
    $ arr [ 'source'] = $ systemParam [ 'source']; // Origin (0- Andrews / 1-IOS / 2-H5 / 3-PC / 4-php / 5- Java)
    $ ARR [ 'Data'] of json_decode = ($ Data, to true); // service parameters json format
    $ arr [ 'method'] = $ data [ 'method']; // access interface, format: model name. method name

    return $arr;
    }

Copy the code

Copy the code

/*

  • @desc Get all header parameters in HTTP header
  • @return array
    */
    private function getAllHeadersParam(){
    $headers = array();
    foreach($SERVER as $key=>$value){
    if(substr($key, 0, 5)==='HTTP
    '){
    $key = substr($key, 5);
    $key = str_replace('_', ' ', $key);
    $key = str_replace(' ', '-', $key);
    $key = strtolower($key);
    $headers[$key] = $value;
    }
    }
    return $headers;
    }

Copy the code

Copy the code

/*

  • @desc signature verification
  • @param $ token server identification string allocated (different clients need to use a different identity)
  • @param $ timestamp string timestamp, UTC time, in Beijing East District 8 (+8) prevail
  • @param $ version string version number
  • @param $ sign string signature
  • @param $ source int Source (0- Andrews / 1-IOS / 2-H5 / 3-PC / 4-php / 5-java)
  • @param $ privatekey string private
  • @param $ data service parameter json format
  • BOOL @return
    * /
    Private function checkAuth (token $, $ timestamp, Version $, $ Sign, Source $, $ PrivateKey, $ Data) {
    // parameter determination
    IF (empty ($ token)) {
    E ( 'token can not be empty ');!
    }
    IF (empty ($ timestamp)) {
    E (' time stamp can not be empty! ');
    }
    IF (empty ($ version)) {
    E (' version number can not be empty ');!
    }
    IF (empty ($ Data)) {
    E ( 'service parameters can not be empty!');
    }
    IF (empty ($ source) && $ source <> '0') {
    E ( 'source can not be empty!');
    }
    IF (empty ($ Sign)) {
    E ( 'signature can not be empty!');
    }
    IF (empty ($ PrivateKey)) {
    E ( 'private keys can not be empty!');
    }
    // check time
    $ expire_second = C ( 'expire_second', null, 10);
    $timestamp_t=$timestamp+$expire_second;
    IF ($ timestamp_t <Time ()) {
    E ( 'request has expired!');
    }
    $ public = D ( 'public');
    $ DATAS = $ this-> Original;
    // system parameter
    $ paramArr = Array (
    ' token '=> $ token,
    ' timestamp '=> $ timestamp,
    ' Version '=> Version $,
    ' Source '=> Source $,
    ' Data '=> Data $,
    );

     //按规则拼接为字符串
     $str = $this->createSign($paramArr,$this->privatekey);
    
     if($str != $this->sign){
         E('验签错误!');
     }
     return true;

    }

Copy the code

sign generation rule and the steps of:

① The first step: all the need to send to the server a request parameters (empty parameter values, file byte stream, except Sign) in ascending order (lexicographical) according to the parameter name in ASCII

note:

  l 参数名ASCII码从小到大排序(字典序);

  l 如果参数的值为空不参与签名;

  l 文件、字节流不参与签名;

  l sign不参与签名;

  l 参数名、参数值区分大小写;

② The second step: the format of parameters in accordance with the sorted key URL (i.e. key1 = value1 & key2 = value2 ...) assembled into a string strA;

③ The third step: after the splicing to give the strA apiKey striSignTemp string, MD5 calculation performed after strSignTemp string lowercase string obtained value as a sign of the end of the incoming service MD5 calculation;

Example (all the parameters, the parameter values ​​are an example, developers can reference format):

token:cd171009328172Ad3sc

apiKey:cd13H2ddd22212ds1da

① The first step (to get a request parameter by parameter name and grew up ASCII codes to large order):

token=cd173309328172Ad322

data={"userName":"18817201899",goods:["addrId":323,{"skuNo":"p12232-023","count":3},{"skuNo":"p12232-013","count":1}]}

timestamp=1507537036

version=v3.6.0

② The second step (according to the rules stitching a string strA):

token=cd171009328172Ad3sc&data={"userName":"18817201899",goods:["addrId":323,{"skuNo":"p12232-023","count":3},{"skuNo":"p12232-013","count":1}]}timestamp=1507537036&version=v3.6.0

③ The third step (generation sign):

1) be signed string strSignTemp:

token=cd171009328172Ad3sc&data={"userName":"18817201899",goods:["addrId":323,{"skuNo":"p12232-023","count":3},{"skuNo":"p12232-013","count":1}]}timestamp=1507537036&version=v3.6.0cd13H2ddd22212ds1da

2) to lower a string

strtolower()

Encrypted 3) MD5 ciphertext

6D556D52822658FD47F7FE362544CEE1
copy the code

/*

  • @desc signature function
  • @param $ paramArr system parameters
  • @param $ apiKey private
  • @return string return signature
    * /
    Private function createSign ($ paramArr, the apiKey $) {
    ksort ($ paramArr);
    $ Sign = '';

    foreach ($paramArr as $key => $val) {
    if ($key != '' && $val != '') {
    $sign .= $key."=".$val."&";
    }
    }
    $sign=rtrim($sign,"&");
    $sign.=$apiKey;
    $sign=strtolower($sign);
    $sign = md5($sign);
    return $sign;
    }

Copy the code

(4) refused to repeat the call: the client first visit, will sign the signature stored in the cache server, the timeout is set to coincide with the time-out time stamp, both in terms of time can ensure consistent within a limited time or timestamp external URL can only be accessed once. If someone uses another visit to the same URL, if you find the cache server already exists for this signature, the denial of service. If the case of the signature in the cache of failure, someone accessed again using the same URL, timestamp timeout mechanism will be intercepted. That is why the time stamp requirement timeout to set consistent with the timestamp of the timeout. Refused repeated calls to ensure that mechanisms URL intercepted by others can not be used (such as data capture).
Copy the code

/**

  • limit the number of request interface @desc
  • BOOL @return
    * /
    Private ask_count function () {
    $ client_ip = $ this-> sys_get_client_ip ();
    $ ask_url = $ this-> sys_GetCurUrl ();
    // limit the number of
    $ limit_num = C ( 'api_ask_limit' , null, 5) ;
    the // valid time, unit: second
    $ limit_time C = ( 'api_ask_time');
    $ now_time = time ();
    $ valid_time now_time = $ - $ limit_time;
    $ ipwhere [ 'creatime'] = Array ( 'the EGT', DATE ( 'Ymd H: I: S', $ valid_time));
    $ ipwhere [ 'ip_name'] = $ client_ip;
    $ ipwhere [ 'ask_url'] = $ ask_url;
    $ check_result = M ( 'log_ip_ask') -> WHERE ($ ipwhere) -> COUNT ();
    IF {($ check_result == '0'!)
    IF ($ check_result> = $ limit_num) {
    E ( 'has exceeded the limit number of times!');
    }
    }
    // insertion
    $ add_data = array (
    'ip_name'=>$client_ip,
    'ask_url'=>$ask_url,
    'creatime'=>date('Y-m-d H:i:s',time())
    );
    $result = M('log_ip_ask')->data($add_data)->add();
    if($result===false){
    E('写入记录失败!');
    }
    return true;
    }

Copy the code

Copy the code

/**

  • Obtain client IP address
  • @param integer $ type returns the type 0 1 return return the IP address IPV4 address numbers
  • @param boolean $ adv whether to acquire advanced mode (there may be disguised)
  • @return mixed
    */
    private function sys_get_client_ip($type = 0,$adv=false) {
    $type = $type ? 1 : 0;
    static $ip = NULL;
    if ($ip !== NULL) return $ip[$type];
    if($adv){
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    $pos = array_search('unknown',$arr);
    if(false !== $pos) unset($arr[$pos]);
    $ip = trim($arr[0]);
    }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
    }elseif (isset($_SERVER['REMOTE_ADDR'])) {
    $ip = $_SERVER['REMOTE_ADDR'];
    }
    }elseif (isset($_SERVER['REMOTE_ADDR'])) {
    $ip = $_SERVER['REMOTE_ADDR'];
    }
    // IP address of the legitimate verification
    $ Long = sprintf ( "% U", ip2long ($ ip));
    $ ip = $ Long Array ($ ip, $ Long): Array ( '0.0.0.0', 0);?
    Return IP $ [$ type];
    }

/**

  • @desc php get the full url address of the current access
  • @return string
    */
    private function sys_GetCurUrl() {
    $url = 'http://';
    if (isset ( $_SERVER ['HTTPS'] ) && $_SERVER ['HTTPS'] == 'on') {
    $url = 'https://';
    }
    if ($_SERVER ['SERVER_PORT'] != '80') {
    $url .= $_SERVER ['HTTP_HOST'] . ':' . $_SERVER ['SERVER_PORT'] . $_SERVER ['REQUEST_URI'];
    } else {
    $url .= $_SERVER ['HTTP_HOST'] . $_SERVER ['REQUEST_URI'];
    }
    return $url;
    }

Copy the code

Whitelist
illegal ip access restrictions, restrictions here are generally used in the interface between the server's call to do this limitation
copy the code

// 允许访问的IP列表    
private $ip_allow = array(
    '111.11.111.111', // 局域网ip
    '111.11.111.112', // 任务服务器
    '111.11.111.113', // 代理IP
);

/**
* @desc 非法IP限制访问
* @param array $config
* @return bool
*/
private function illegalip(){
if(!$this->ip_limit){
return true;
}
$remote_ip = get_client_ip();
if(in_array($remote_ip, $ip_allow)){
return true;
}
return false;
}

Copy the code

Reference link: https: //www.jianshu.com/p/c6518a8f4040

App open interface api security -Token signature sign of Design and Implementation
Introduction

In the app open interface api design, can not avoid is the security issue, because most interfaces related to the user's personal information and sensitive data, so these interfaces need to be authenticated identity, then it requires the user to provide some information, such as user name and password, etc., but for safety reasons so that the number of users exposed plaintext password as possible, we are generally in a web project, in most cases, the saved session, and then to keep a cookie, to keep answer the validity of the user. But in the open interface provided by the app, the back-end server How to verify a user logs in after landing and maintain the effectiveness of the user of it, the following items are reference design solutions, the principle and most secure authentication as open interfaces, such as Taobao open interface token validation, verification token micro-channel development platform is empathy.

Signature design
for sensitive api interface, you need to use the https protocol

https is added to the hypertext transfer protocol http SSL layer, between which a communication network is encrypted, an encryption certificate is required.

https protocol requires ca certificate, generally require payment.

Signature design

How it works: Users log on to the server to provide user authentication information (such as account and password), the authentication server to the client to return after a Token token, when the user gets information again, take this token, if the token Zhengqu Returns data. For obtaining the Token information, access user interfaces, client request url need to take the following parameters:

Timestamp: timestamp

Token Ryopai: token

Then all parameters requested by the user in alphabetical order (including timestamp, token), then more MD5 encryption (you can add some salt), all caps, generate sign signature, which is called url signature algorithm. Then the user login information each call, take sign, timestamp, token parameters.

For example: The original request https://www.andy.cn/api/user/update/info.shtml?city= Beijing (post and get the same, sort all encryption parameters)

Stamped and token

https://www.andy.cn/api/user/update/info.shtml?city= Beijing × tamp = 12445323134 & token = wefkfjdskfjewfjkjfdfnc
then more url parameter generating sign

The final request

12445323134 & token = wefkfjdskfjewfjkjfdfnc & sign = FDK2434JKJFD334FDF2 https://www.andy.cn /api/user/update/info.shtml?city= Beijing × tamp =
final principle is to reduce the number of exposed plaintext; data security access.

Specific achieve the following:

  1. api request client wants a server sends a user authentication information (username and password), the server-side request to change requests, verify that the user information is correct.

If it is correct: a unique non-repeating string is returned (typically UUID), and then maintain user information relationship Token ---- Uid in Redis (any cache server), so that other api check for the token.

If the error: error code is returned.

2. The server design a url request blocking rules

(1) determines whether or not containing timestamp, token, sign parameters, return an error code if not contained.

(2) determination server receives the request and the time stamp parameters differ by a very long time (half an hour of time, such as custom), it indicates that the url exceeds expired (url if stolen, he changed the time stamp, but can lead to unequal sign signature).

(3) determine whether the token is valid, according to the request over the token, the query redis cache uid, if not get this indicates that the token has expired.

(4) The url parameters of the user request, the server generates signature sign according to the same rules, the signature comparison for equality, are equal release. (Natural url signature can not guarantee 100% security, but also can encrypt data and url, but if this can not be sure that the public key is lost through a public key AES, so only the signature large part to ensure safety).

(5) just to get this url intercept authentication url release (such as landing url), all the rest are subject to the url interception.

3.Token and relationship maintenance Uid

We need to create a user login token - uid relationship, you need to be deleted when the user exits the token - the relationship uid.

Signature Algorithm

Get all request parameters
duplicated code

String sign = request.getParameter("sign");
Enumeration<?> pNames = request.getParameterNames();
Map<String, Object> params = new HashMap<String, Object>();
while (pNames.hasMoreElements()) {
String pName = (String) pNames.nextElement();
if("sign".equals(pName))continue;
Object pValue = request.getParameter(pName);
params.put(pName, pValue);
}

Copy the code

Generating a signature

Copy the code

public static String createSign(Map<String, String> params, boolean encode)
throws UnsupportedEncodingException {
Set keysSet = params.keySet();
Object[] keys = keysSet.toArray();
Arrays.sort(keys);
StringBuffer temp = new StringBuffer();
boolean first = true;
for (Object key : keys) {
if (first) {
first = false;
} else {
temp.append("&");
}
temp.append(key).append("=");
Object value = params.get(key);
String valueString = "";
if (null != value) {
valueString = String.valueOf(value);
}
if (encode) {
temp.append(URLEncoder.encode(valueString, "UTF-8"));
} else {
temp.append(valueString);
}
}

    return MD5Utils.getMD5(temp.toString()).toUpperCase();
}

https://www.cnblogs.com/whcghost/p/5657594.html

Guess you like

Origin www.cnblogs.com/djwhome/p/12536305.html