后台服務端接口驗證項目實例~~


前言:

    在當前開放互聯的大環境下,接口互通成了最最普通常見數據通訊與交互的一種方式;接口測試的重要性也是不言而喻,但卻成了普通功能測試人員的一道屏障;特別是服務端的接口驗證更是麻煩;這里拋磚引玉希望更多童鞋參與多多討論。

場景&描述:

    c1->s1->s2

          s1 <-s2

協議:http

c端,發起c1(pay)請求,服務端處理完畢,通過s1接口把(pay)請求支付接口告訴指定s2服務地址;s2服務地址解析s1接口內容,正常返回SUCCESS,異常返回FAILURE;s1收到s2返回內容做對應業務處理。

接口消息格式:json,簽名驗簽rsa標准算法,消息體url編碼。

請求方式:post

 

測試對象:

   s1接口

 

測試范圍:

接口測試之常規測試維度,從宏觀到微觀一一細分拆借大概思路:消息發送方式、消息體是否為null、消息體格式是否正確、消息解密是否正確、消息體中json體key鍵檢查(必填值是否缺省、缺省值是否存在、是否多多余key鍵)、消息體中json體values值檢查(必填值檢查是否缺省、缺省值是否存在、值類型檢查,特別是數字類型的,比如交易金額啥的)。

接口測試之安全維度,ip黑白名單,消息體參數注入,摘要解密算法研究等。

1.消息發送方式

2.消息體是否為null和格式檢查

3.json,key鍵必填字檢查

4.json,values值檢查

5.業務數據檢查,比如收到SUCCESS檢查。

6.其它

 

實現技術分析:

如果只要驗證第5點,簡單的只要模擬s2,最快速高效的方法,直接在tomcat下,新建一個工程,創建一個html文件,內容為SUCCESS或FAILURE;然后s1接口直接往這個地址發送就好(http協議)。

http協議,后台實現,最方便的還是java,也有python的,依賴的包太多,看個人條件選擇;如果是soket套接字,建議與加密解密類語言保持一致比較好,因為解密太折騰人了,哎。

這里選擇了一個java,servlet來實現。

再回頭看s1接口,所以的參數都不是固定的,每次發生請求的參數都是動態的,這樣的話,自己去實現這個servlet的時候,參數化的部分,就直接考慮連接db,這樣就不需要考慮s1接口傳入固定的值,動態的去db查詢s1接口參數相關數據信息(特別是解密,與json,values值驗證,和功能業務特性,每次填寫固定參數值肯定不靠譜)。

-- jdbc

 

package com.iapppay.jdbc;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class mysqljdbc {
    public Connection conn;
    public Statement st;
    public ResultSet rs;
    
    public Connection getConn() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://192.168.0.151/iapppay?useUnicode=true&characterEncoding=utf-8","root","aibei1010");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }
    
    public String getappkey(String appid,String key){
        String appkey =null;
        //String sql = "select waresid,platpkey,platvkey,cppkey,cpvkey from wares where waresid = '3000713545';";
        String sql = "select waresid,platpkey,platvkey,cppkey,cpvkey from wares where waresid = "+appid+"";
        conn = getConn();
        try{
             st = conn.createStatement();
             rs = st.executeQuery(sql);
             while(rs.next()){
                 appkey = rs.getString(key);
             }
            
        }catch(SQLException e)
        {
            e.printStackTrace();
        }
        return appkey;
        
    }
    
    public void insertData(String data,String rmark,String status){
        int r = 0;
        String sql = "insert into cptest values(null,"+"'"+data+"',"+"'"+rmark+"'," +"'"+status+ "');";
        conn = getConn();
        try{
             st = conn.createStatement();
             r = st.executeUpdate(sql);
             if(r != '0'){
                 System.out.println("新增數據成功過");
             }else
             {
                 System.out.println("新增數據成失敗");
             }
            
        }catch(SQLException e)
        {
            e.printStackTrace();
        }
        
    }
    
    public String getStringData(String data)
    {
        String dataString = null;
        for (int i = 0;i<data.length();i++)
                {
                dataString += data.charAt(i);
                dataString = data.replace("\"","\\'"); 
                }
        return dataString;
    }
 
    
}
View Code

 

--servlet

 

<?xml version="1.0" encoding="UTF-8"?>  
<web-app version="2.5"   
    xmlns="http://java.sun.com/xml/ns/javaee"   
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  
    <servlet>  
        <servlet-name>CpDataTest</servlet-name>  
        <servlet-class>  
            com.iapppay.service.CpDataService  
        </servlet-class>  
        <load-on-startup>1</load-on-startup>  
    </servlet>  
    <servlet-mapping>  
        <servlet-name>CpDataTest</servlet-name>  
        <url-pattern>/CpDataTest</url-pattern>  
    </servlet-mapping>  
</web-app> 
View Code

 

 

package com.iapppay.service;

import java.io.IOException;  
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.util.Map;

import javax.servlet.ServletException;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  

import com.iapppay.jdbc.mysqljdbc;

import net.sf.json.JSONObject;
  
public class CpDataService extends HttpServlet{  
  
    private String getData(boolean i){  
        if (i){
                StringBuffer sb = new StringBuffer();  
                sb.append("SUCCESS");  
                return sb.toString();
        }else
        {
                 StringBuffer sb = new StringBuffer();  
                sb.append("FAILURE");  
                return sb.toString();
            
        }
    }  
      
    @Override  
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)  
            throws ServletException, IOException {  
        // TODO Auto-generated method stub  
        String rmark = "cp交易結果通知測試地址,請用post方式請求!";      
        resp.setContentType("text/html;charset=utf-8");  
        resp.getOutputStream().write(rmark.getBytes("utf-8"));
    }  
   
    @Override  
    protected void doPost(HttpServletRequest req, HttpServletResponse resp){  
        // TODO Auto-generated method stub  
//      super.doPost(req, resp);  
        CpDataService cp = new CpDataService();
        mysqljdbc db = new mysqljdbc();
        HttpServletRequestTest reqTest = new HttpServletRequestTest();
    
        //接受HttpServletRequest發送消息體內容
        Map<String, String[]> params = req.getParameterMap();  
        String queryString = "";  
        for (String key : params.keySet()) {  
            String[] values = params.get(key);  
            for (int i = 0; i < values.length; i++) {  
                String value = values[i];  
                queryString += key + "=" + value + "&";  
            } 
        }
        
        try{    
            if(queryString != null && reqTest.httpReqTest(req)){
                String transdata = req.getParameter("transdata");
                //密鑰驗簽驗證,消息體驗證,消息體必填字驗證    
                String data = cp.getData(reqTest.rsaTest(req)&&reqTest.httpReqTest(req)&&reqTest.httpReqJsonTest(transdata));
                //
                String rmark = "rsa密鑰簽名驗證結果:"+reqTest.rsaTest(req)+"\\n"
                +reqTest.httpReqTest(req, "test")+"\\n"
                +reqTest.httpReqJsonTest(transdata, "test")+"\\n";
                
                db.insertData(queryString, rmark, data);
                resp.setContentType("text/html;charset=utf-8");  
                resp.getOutputStream().write(data.getBytes("utf-8")); 
                
            }else{
                String data = cp.getData(false);
                db.insertData(queryString, "發送消息體為NULL或transdata為NULL,密鑰驗證失敗", data);
                resp.setContentType("text/html;charset=utf-8");  
                resp.getOutputStream().write(data.getBytes("utf-8"));
            }
       
        }
        catch (Exception e)
        {    
            String data = cp.getData(false);
            resp.setContentType("text/html;charset=utf-8");  
            try {
                resp.getOutputStream().write(data.getBytes("utf-8"));
            } catch (UnsupportedEncodingException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } 
        }
    }  
    
//    public static void main(String[] args) {
//        
//        jsonAction jc = new jsonAction();
//        CpDataService cp = new CpDataService();
//        mysqljdbc db = new mysqljdbc();
//        HttpServletRequestTest reqTest = new HttpServletRequestTest();
//        String transdata = "{\"appid\":\"3000128894\",\"appuserid\":\"abc\",\"cporderid\":\"598989898986563333\",\"cpprivateinfo\":\"3333Test\",\"currency\":\"RMB\",\"notifyurl\":\"http://192.168.0.157:9888/Test/CpDataTest\",\"price\":300,\"waresid\":1,\"waresname\":\"test\"}";
//        String sign = "f5eKXIS6EF3Ey2M2pAG3gJyjWRGCkkwYfHpq16X+jiQ2bbnq6wMD3g41koA9UL2SwvgYVeBpCYUeGLZITs0vVQePmpcKxsg4qqnC711bchqnfaHGDgr0QUHoYYwjfl6PPN+/hlTvHukmRNLUq/xV32Cl0QidMRj9FOWm1OxRK70=";
//        String signtype = "RSA";
//        String dataTest = null;
//        JSONObject jo = JSONObject.fromObject(transdata);
//        String appid = jo.getString("appid");
//        String data = cp.getData(jc.cpsignTest(appid, sign, transdata));
//        System.out.println(reqTest.httpReqJsonTest(transdata,"Test"));
//        System.out.println(reqTest.httpReqJsonTest(transdata));
//        db.insertData(transdata+sign+signtype, "sign解密驗簽驗證", data);
//        System.out.println(appid);
//        System.out.println(data);
//    }
}  
View Code

 

 

 

--jsp監控界面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.sql.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<%
    String path = request.getContextPath();
    int recordCount=0;
    String stat = request.getParameter("stat") == null ? "" : request.getParameter("stat");
    Class.forName("com.mysql.jdbc.Driver").newInstance();
    Connection con=java.sql.DriverManager.getConnection("jdbc:mysql://192.168.0.151/iapppay?useUnicode=true&characterEncoding=utf-8","root","aibei1010");
    Statement stmt=con.createStatement();
    String sql = "";
    if(!stat.equals("")){
         sql = "select id,data,rmark,status from cptest where status='" + stat + "' order by id desc";
    }else{
         sql = "select id,data,rmark,status from cptest order by id desc";
    }
     ResultSet rst=stmt.executeQuery(sql);
     
     String sums = "select count(*) from cptest";
     
     Statement stmt2 = con.createStatement();
     ResultSet rst2 = stmt2.executeQuery(sums);
     
     if(rst2.next()){
          recordCount = rst2.getInt(1);
    }
%>
<style media="screen" type="text/css">
body { font-family: verdana, arial, helvetica, sans-serif; font-size: 80%; }
table { font-size: 100%; }
pre { }
/* -- heading ---------------------------------------------------------------------- */
h1 {
font-size: 16pt;
color: gray;
}
.heading {
margin-top: 0ex;
margin-bottom: 1ex;
}
.heading .attribute {
margin-top: 1ex;
margin-bottom: 0;
}
.heading .description {
margin-top: 4ex;
margin-bottom: 6ex;
}
.overflow{
overflow:auto;
} 
#show_detail_line {
    margin-top: 3ex;
    margin-bottom: 1ex;
}
</style>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>交易結果通知測試監控</title>
</head>
<body>

<div class='heading'>
<h1>愛貝交易結果通知監控</h1>
<a href='index.jsp?stat=SUCCESS'>SUCCESS</a>
<a href='index.jsp?stat=FAILURE'>FAILURE</a>
<a href='index.jsp'>All</a>
</div>

<div class = 'heading'>
<table border=1 style="table-layout:fixed;word-wrap:break-word;" width="100%" id = 'overflow' >
<tr>
<td width ="3%">ID</td>
<td width ="20%">接受報體內容</td>
<td width ="20%">驗證點</td>
<td width ="5%">返回結果</td>
</tr>
<% 
         while(rst.next())
         {
             out.println("<tr>");
             out.println("<td>"+rst.getString("id")+"</td>");
             out.println("<td>"+rst.getString("data")+"</td>");
             out.println("<td>"+rst.getString("rmark")+"</td>");
             out.println("<td>"+rst.getString("status")+"</td>");
             out.println("</tr>");
         }
         //關閉連接、釋放資源
         //<a href="http://www.w3chtml.com/" target="_blank">
         //+"&nbsp;"+"width=50"+"height=50"
        %>
</table>
</div>
</body>
</html>
<% 
rst.close();
rst2.close();
stmt.close();
stmt2.close();
con.close();     
%>
View Code

 

 

 

--效果圖

 

后續:

拋磚引玉,歡迎探討~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM