zoukankan      html  css  js  c++  java
  • 后台服务端接口验证项目实例~~

    前言:

        在当前开放互联的大环境下,接口互通成了最最普通常见数据通讯与交互的一种方式;接口测试的重要性也是不言而喻,但却成了普通功能测试人员的一道屏障;特别是服务端的接口验证更是麻烦;这里抛砖引玉希望更多童鞋参与多多讨论。

    场景&描述:

        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

    --效果图

    后续:

    抛砖引玉,欢迎探讨~

  • 相关阅读:
    Grovvy初识
    在eclipse中安装插件
    解决 APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tas
    Axis2 webservice入门--Webservice的发布与调用
    一步一步教你自定义博客园(cnblog)界面
    Enum枚举
    并行与并发
    多线程join(加入)
    守护线程
    停止线程
  • 原文地址:https://www.cnblogs.com/webtest/p/4210389.html
Copyright © 2011-2022 走看看