天天看点

(四)java+testng+poi之接口鉴权

1、HTTP是无状态协议

什么是无状态?就是说这一次的请求和上一次的请求是没有任何关系的,无法共享信息。好处就是速度快。

2、cookie、session的加入

HTTP请求是无状态的,所以解决共享信息的问题必须采用其他的手段,于是就有了sessionid,sessionid是基于cookie实现的。服务器为每一个用户生成一个不一样的随机字符串,每次向服务器发起HTTP请求时,都会把这个字符串传给服务器,这样就能区分用户了。

3、session的缺点

对于客户端来说session是非常好的,只需要cookie中存一个字符串就好了,但对于服务器来说,必须存储所有在线用户的session,那么这就占用了很大的资源(cpu,内存),严重影响服务器的性能。这时可以选择去扩展服务器做集群,但是同时也出现了分布式session的问题,那么可以采用session粘滞或者session集中式管理(redis)来解决。

4、cookie、session的区别

cookie:客户端和服务端都能生成cookie,存放在客户端。存放一些不敏感的数据,数据类型只能是字符串(json).

session:服务端生成session,存放在服务端。可以存放任意数据,Java中session中可以存放任意对象,session必须依赖cookie实现。

5、token 票据的意思,就是门票、令牌

token也是一个字符串,用户输入用户名和密码之后,向服务器发起请求,服务器会生成一个token串,token串是由header+userid+时间戳,在经过一个加密的算法,生成一个token字符串。

token验证原理图:

(四)java+testng+poi之接口鉴权

session和token的区别:

session:服务器生成、存储、验证,以cookie的方式传给客户端,客户端以同样的方式发送给服务端。session有状态。

token:服务器生成、验证,以cookie或者请求头的形式传给客户端,客户端以同样的方式发送给服务器,token无状态。

思路:

接口鉴权需要的session或者token,可以从登陆响应报文或者响应头里面达到信息。然后存储起来。别的接口需要鉴权的时候,再把session和token设置好就可以。

比如登陆操作,接口登陆成功后,获取response,用jsonpath提取出token,然后把token存放在map中。map模拟的是一个环境变量。

/**
	 * 登陆
	 * @param api
	 * @param case1
	 */
	@Test(dataProvider="login")
	public void loginTest(Api api,Case case1) {
		String uri=api.getUrl();
		String type=api.getType();
		String params=case1.getParams();
		String contentType=api.getContentType();
		//登陆接口,默认不需要鉴权
		String response=HttpUtil.call(uri, type, params, contentType);
		//token存储
		AuthorizationUtils.storeTokenAndMemberId( response);
//		System.out.println(AuthorizationUtils.environmentMap.get("token"));
	}

	//模拟环境变量,map随着类的加载而加载。
	public static final Map<String,String> environmentMap=new  HashMap<String,String>();
	/**
	 * 存储token
	 * @param response
	 */
	public static void storeTokenAndMemberId(String response) {
		try {
		Object token=JsonPath.read(response, "$.data.token_info.token");
		//如果token不为空,则存储到map中
		if(token!=null) {
			environmentMap.put("token", token.toString());
			Object memberId=JsonPath.read(response, "$.data.id");
			if(memberId!=null) {
				//如果memberId不为空,则存储到map中
				environmentMap.put("memberId", memberId.toString());
			}
		}
		}catch(Exception e) {
			e.printStackTrace();
		}
		
	}

           

那么充值接口请求的时候,首先获得token,然后在请求头里面添加鉴权信息。

以下代码为充值接口的用例

/**
	 * 充值测试
	 * @param api
	 * @param case1
	 */
	@Test(dataProvider="recharge")
	public void rechargeTest(Api api,Case case1) {
		String uri=api.getUrl();
		String type=api.getType();
		String params=case1.getParams();
		String contentType=api.getContentType();
		HttpUtil.call(uri, type, params, contentType,true);
	}
           

以下代码为调用post请求

/**
	 * post提交数据方式:application/json
	 * 
	 * @param uri
	 * @param params          application/json
	 * @param isAuthorization 是否需要鉴权
	 */
	public static String doPost(String uri, String params, boolean isAuthorization) {
		try {
			// 创建post请求,用父类接受子类
			HttpPost post = new HttpPost(uri);
			// 添加请求头
			post.addHeader(Constants.HEADER_MEDIA_TYPE_NAME, Constants.HEADER_MEDIA_TYPE_VALUE);
			post.addHeader(Constants.CONTENT_TYPE, Constants.CONTENT_TYPE_JSON);
			if (isAuthorization == true) {
				AuthorizationUtils.setTokenInRequest(post);
			}
			// 设置body
			post.setEntity(new StringEntity(params, "utf-8"));
			// 创建客户端
			HttpClient client = HttpClients.createDefault();
			// 发送请求
			HttpResponse response = client.execute(post);
			return getResult(response);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

           

以下代码为设置请求头的鉴权内容

/**
	 * 设置请求头的token
	 * @param request
	 */
	public static void setTokenInRequest(HttpRequest request) {
		try {
			//从环境变量中取到token的值
			String value=environmentMap.get("token");
			if(value!=null) {
				//在头里添加token
				request.addHeader("Authorization", "Bearer "+value);
				
			}
		}catch(Exception e) {
			//捕获异常
			e.printStackTrace();
		}
	}
           

继续阅读