java实现自动化测试接口访问(二)--Http登录授权接口实例

1.待测试的接口说明

1、自己写的一个登录功能,通过加密算法获得私钥,token还有cookie,通过Postman访问该接口

  1. 接口的地址:http://localhost:8080/login
  2. 请求的方式:post
  3. 请求的结果:
    这里写图片描述
    这里写图片描述

2、测试目标
登录成功后,返回是否返回预期的状态和token

2.新建Java web项目

1、工程结构说明
这里写图片描述

2、User.java源码

package com.test.entities;

/**
 * 用户实例,每个字段对应数据库user表的每个字段
 */
public class User {
    private String username;
    private String password;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + "]";
    }
}

3、JdbcUtils.java源码

package com.test.utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
 * 数据库连接常用类
 *
 */
public class JdbcUtils {
    /**
     * 进行数据库连接,并返回连接对象
     * @return 数据库连接对象
     * @throws Exception
     */
    public static Connection getConnection() throws Exception {
        String url = "jdbc:mysql:///数据库名?characterEncoding=utf8&useSSL=false";
        String username = "用户名";
        String password = "密码";
        String driver = "com.mysql.jdbc.Driver";
        Class.forName(driver); // 将数据库连接驱动driver加载到内存中
        return DriverManager.getConnection(url, username, password); // 返回连接对象 
    }
    /**
     * 关闭数据库连接的静态方法
     * @param conn 需要关闭的连接对象
     * @param stmt 需要关闭的语句对象 
     * @param rs 需要关闭的查询结果对象
     */
    public static void close(Connection conn, Statement stmt, ResultSet rs) {
        if(rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

4、UserDao.java源码

package com.test.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.test.entities.User;
import com.test.utils.JdbcUtils;
public class UserDao {
    /**
     * 根据给定的sql和参数进行数据库查询,并将结果转成对象返回
     * @param sql 需要执行的select语句
     * @param args select查询语句中占位符所需的参数
     * @return select查询后返回的对象集合
     */
    public List<User> getUsers(String sql, Object...args){
        List<User> users = new ArrayList<>();
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection(); // 获取数据库连接
            ps = conn.prepareStatement(sql); // 创建带有占位符的语句对象
            for(int i = 0; i < args.length; i++) {
                ps.setObject(i+1, args[i]); // 对占位符进行实际赋值
            }
            rs = ps.executeQuery(); // 执行sql语句,并获取返回
            while(rs.next()) { // 根据返回进行记录的逐条遍历
                User _user = new User();
                _user.setUsername(rs.getString("username"));
                _user.setPassword(rs.getString("password"));

                users.add(_user); // 每一条记录代表一个user对象,添加到集合中
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.close(conn, ps, rs); // 关闭数据库连接 
        }
        return users;
    }
}

5、Authorization .java源码

package com.test.entities;
/**
 * 返回给成功登录的授权用户当前的token
 *
 */
public class Authorization {
    /**
     * 状态信息
     */
    private String status;
    /**
     * token信息
     */
    private String token;
    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }
    public String getToken() {
        return token;
    }
    public void setToken(String token) {
        this.token = token;
    }
    @Override
    public String toString() {
        return "Authorization [status=" + status + ", token=" + token + "]";
    }
}

6、SearchError .java源码

package com.test.entities;
/**
 * 用于返回用户各类访问错误的实例
 *
 */
public class SearchError {
    /**
     * 错误编号
     */
    private int errorCode;
    /**
     * 错误信息
     */
    private String message;
    public int getErrorCode() {
        return errorCode;
    }
    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    @Override
    public String toString() {
        return "SearchError [errorCode=" + errorCode + ", message=" + message + "]";
    }
}

7、UserService .java源码

package com.test.services;

import java.util.ArrayList;
import java.util.List;
import com.test.dao.UserDao;
import com.test.entities.User;

public class UserService {

    /**
     * 用于对输入指定筛选条件信息数据库查询的方法
     * @param userName 用户名
     * @param password 密码
     * @return 所有符合条件的user对象集合
     */
    public List<User> getUsers(String userName, String password){
        List<User> users = null;
        String sql = "select * from tb_User where "; // 不完整的sql语句,最后的where用于和之后的筛选条件拼接
        List<Object> listArgs = new ArrayList<>(); // 用于输入到sql中的占位参数,对应sql中“?”占位符
        if(userName!=null && !userName.equals("")) { // 如果username不为空

            sql = sql + "username=? and ";  // sql语句中拼接username的筛选条件
            listArgs.add(userName); // 将username的值加入到参数中
        }
        if(password!=null && !password.equals("")) { // 如果password不为空
            sql = sql + "password =? and"; // 拼接password的筛选条件
            listArgs.add(password); // 将查询条件加入参数集合中
        }
         // 最后拼接1=1恒true表达式,用于结尾,否则sql最后留下一个and关键字,语法错误
        sql=sql+"and 1=1";
        UserDao userDao = new UserDao();
        users = userDao.getUsers(sql, listArgs.toArray()); // 将组织好的sql,和传递的参数交给DAO进行数据库实际访问
        return users;
    }
}

8、BearerToken .java源码

package com.test.utils;

import java.util.Date;
import javax.crypto.SecretKey;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
/**
 * 用于生成token
 *
 */
public class BearerToken {
    /**
     * 生成token的静态方法 
     * @param key 加密私钥
     * @param username 授权用户的用户名
     * @param expir token过期时间
     * @return token字符串
     */
    public static String createToken(SecretKey key, String username, Date expir) {
        SignatureAlgorithm sa = SignatureAlgorithm.HS256; // 设置签名算法
        JwtBuilder builder = Jwts.builder()
                .setAudience(username) // 授权用户
                .setExpiration(expir) // 过期时间
                .signWith(sa, key); // 签名算法和私钥 
        return builder.compact();
    }
}

9、CreateKey .java源码

package com.test.utils;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
/**
 * 用于生成私钥
 *
 */
public class CreateKey {
    /**
     * 生成私钥的静态方法
     * @return
     */
    public static SecretKey genKey() {
        String seed = System.currentTimeMillis()+""; // 私钥的生成是根据当前系统时间的毫秒表达式
        return new SecretKeySpec(seed.getBytes(), "AES"); //通过AES算法将字节数组加密为私钥 
    }
}

10、Login.java源码-实现用户登录授权的接口

package com.test.jk;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.List;

import javax.crypto.SecretKey;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.test.entities.Authorization;
import com.test.entities.SearchError;
import com.test.entities.User;
import com.test.services.UserService;
import com.test.utils.BearerToken;
import com.test.utils.CreateKey;

/**
 * Servlet implementation class Login
 * 实现用户登录授权的接口,要求用户通过post请求传递user和pwd两个参数,分别代表用户的注册用户名和密码。
 * 如果用户名和密码校验成功,则会生成一小时有效的token,并将token返回给用户,同时在用户端生成cookie,用于记录过期时间。
 */
public class Login extends HttpServlet {
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String username = request.getParameter("user");
        String password = request.getParameter("pwd");
        Gson gson = new GsonBuilder().create();
        String json = null;
        if (username != null && password != null) { // 如果用户名和密码不为空
            List<User> user=new UserService().getUsers(username, password);//使用数据库数据来校验用户名和密码
            if (user.size()>0) {
                SecretKey key = null;
                Object obj = getServletContext().getAttribute("secretKey");
                if(obj==null){//如果没有secretKey属性,则说明之前未生成过服务器端加密用的私钥
                    key=CreateKey.genKey();//获得一个新的私钥
                    getServletContext().setAttribute("secretKey", key);
                }else{
                    key=(SecretKey)obj;
                }
                Date expir=new Date(System.currentTimeMillis()+3600000);//设置token的过期时间为一个小时
                Authorization auth=new Authorization();
                auth.setStatus("authoried");//将返回对象的status属性设为已授权
                auth.setToken(BearerToken.createToken(key, username, expir));//调用createToken方法对用户名和过期时间进行签名生成token
                json=gson.toJson(auth);//将auth对象转成json格式
                Cookie cookie=new Cookie("expir", expir.getTime()+"");//设置客户端需要保存的cookie,名字是expir,值时过期时间的毫秒表达式
                cookie.setMaxAge(3600);//设置cookie过期的时间是1小时
                response.addCookie(cookie);//将cookie发送到客户端
            } else {//如果用户名和密码不正确,设置错误返回对象
                SearchError error = new SearchError();
                error.setErrorCode(101);
                error.setMessage("错误的用户名或密码");
                json = gson.toJson(error);
            }
        } else {//当未提交用户名或者密码,则设置错误返回对象
            SearchError error = new SearchError();
            error.setErrorCode(102);
            error.setMessage("未提供用户名和密码进行身份验证");
            json = gson.toJson(error);
        }
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json");
        PrintWriter out = response.getWriter();
        out.print(json);
        out.flush();
    }

}

4、使用PostMan访问地址接口

1、启动eclipse的tomcat服务
2、在PostMan新建一个Request,输入地址,选择请求方法
3、在body里面输入用户名和密码(数据库已注册的用户名密码)
4、点击send按钮
这里写图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41508948/article/details/81976858
今日推荐