后台服务端接口验证项目实例~~

前言:

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

场景&描述:

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;
    }

}

--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> 

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);
//    }
}  

--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();
%>

--效果图

后续:

抛砖引玉,欢迎探讨~

时间: 2024-08-02 22:36:23

后台服务端接口验证项目实例~~的相关文章

api服务端接口安全

api服务端接口安全性解析 http://blog.csdn.net/tenfyguo/article/details/8225279 常用的基于token的实现方案 http://blog.csdn.net/tenfyguo/article/details/8225279 token常常用在各种应用中,如下场景: 1,用户输入密码和帐号后,系统进行验证后,生成一个session,分配一个sessionid给使用者,后续服务使用者就无需每次都输入密码和验证密码了,只需把对应的帐户和session

移动端与PHP服务端接口通信流程设计(增强版)

增强地方一: 再增加2张表,一个接口表,一个授权表,设计参考如下: 接口表 字段名 字段类型 注释 api_id int 接口ID api_name varchar(120) 接口名,以"/"作为分割线,如 blog/Index/addBlog api_domain varchar(256) 所属领域 is_enabled tinyint(1) 是否可用  1:可用 0:不可用 add_time int 添加时间(戳) (注:只列出了核心字段,其它的再扩展吧!!!) 授权表 字段名 字

api服务端接口安全性解析针对

针对 --->非开放性平台 --->公司内部产品 接口特点汇总: 1.因为是非开放性的,所以所有的接口都是封闭的,只对公司内部的产品有效: 2.因为是非开放性的,所以OAuth那套协议是行不通的,因为没有中间用户的授权过程: 3.有点接口需要用户登录才能访问: 4.有点接口不需要用户登录就可访问: 针对以上特点,移动端与服务端的通信就需要2把钥匙,即2个token.第一个token是针对接口的(api_token):第二个token是针对用户的(user_token): 先说第一个token(

App架构设计经验谈:服务端接口的设计

转自:http://www.jb51.net/article/60796.htm App与服务器的通信接口如何设计得好,需要考虑的地方挺多的,在此根据我的一些经验做一些总结分享,旨在抛砖引玉. 安全机制的设计 现在,大部分App的接口都采用RESTful架构,RESTFul最重要的一个设计原则就是,客户端与服务器的交互在请求之间是无状态的,也就是说,当涉及到用户状态时,每次请求都要带上身份验证信息.实现上,大部分都采用token的认证方式,一般流程是: 用户用密码登录成功后,服务器返回token

SpringMVC 利用HttpPost向服务端接口上传文件

现在Spring的广泛使用使得以前我们在做文件上传的不需要对数据进行转码传输,MultipartEntity内封装了各种方法,我们可以直接在客户端实例化 MultipartEntity类将需要上传的文件以参数的形式写入HttpPost的Entity,这样类似与在前端使用form表单提交来实现文件上传,区别是前端我们是在form里面设定enctype="multipart/form-data"这个参数.废话不多说,下面是代码: 首先是客户端: import java.io.File; i

Java后台服务端接入腾讯IM

最近因为公司项目需求,需要在后台接入腾讯的IM(云通信)功能,于是如火如荼的去研究腾讯IM的文档,然而发现操蛋的是腾讯居然没有给Java后台端提供SDK,于是我们后台只能通过HTTP的方式请求对应的rest api的来达到目的,下面给出具体过程: 1.首先,我们需要注册一个账号,这个只需通过手机扫码登陆即可(按步骤来,好像需要支付一分钱,具体忘了)   2.接下来需要找到云通信功能,创建应用,这里需要保留一些东西:SDKAPPID,accounttype,账号管理员(identifier)以及公

基于CXF框架下的SOAP Webservice服务端接口开发

最近对webservice 进行入门学习,网上也是找了很多的学习资料.总得感觉就是这了解点,那了解点.感觉不够系统,不够容易入门.差不多断断续续看了一个星期了,今天小有成果,把客户端,服务端都搞定了.我先写服务端,在说客户端. 框架:服务端webservice是spring+cxf的maven工程. 环境:jdk1.7+maven3.3.9+tomcat7 新建maven工程可以参考我之前的博客:使用eclips创建Maven项目. 1.引入开发的依赖.pom.xml<project xmlns

POSTMAN测试SpringMVC RESTFul风格的服务端接口始终得不到值

后台接口中接收参数使用DataObject(包含一个String类型的属性data)     ServletRequestDataBinder binder = new ServletRequestDataBinder(new DataObject());     binder.bind(request); 然后再POSTMAN中使用如图的方式传参: 可以发现得到的返回值是null,而且根据后台调试,确实没有得到传入的参数.切回x-www-form-urlencoded模式下然后将此对象用如下方

API开发第四篇:定义客户端/服务端接口协议

在进行API开发的时候,需要事先定义好app与server交互的数据格式,这样前端人员与服务端人员才能够事先决定好如何获取数据.如何解析数据.如何传输协议. 在我看来目前接口协议无外乎这三种情况: 1. json数据进行交互 2. xml数据进行交互 3. 自定义数据格式交互 自定义数据格式进行前后端的数据交互,需要花费较大的精力,而且需要很有经验的人设计的协议才会确保各个平台的兼容以及良好的可阅读性.并且解析.封装都需要自己来用代码实现,很多第三方库都没办法用上.因为这里我不进行讨论.主要说说