您的位置:首页 > 理论基础 > 计算机网络

Android 实现request HTTP authentication(授权认证开发)

2017-12-06 12:39 489 查看
这几天开发对外的SDK,可以实现登陆,支付。类似开发一套QQ,微信第三方登陆。使用的是OAuth 2.0的授权协议。其中用到了 Http Authentication,查阅网上资料,各种答案都有,有的不知道有没有验证,有的相关API已经过期。

如果通过抓包工具(Charles)可对比观察Authentication请求效果


         


图一是有设置认证的Post请求,   图二是一般的Post网络请求

第一行代码是OKhttp自带的可以添加OAuth的方法,但是按这种方式联调一直不成功也没找到原因,如果有用这种方式成功请求通过的可以说一下注意事项。

//第一个参数为用户名,第二个参数为密码
final String basic = Credentials.basic("zhangsan", "123456");
OkHttpClient client = new OkHttpClient.Builder()
.authenticator(new Authenticator() {
@Override
public Request authenticate(Route route, Response response) throws IOException {
return response.request().newBuilder().header("Authorization", basic).build();
}
})
.build();
Request request = new Request.Builder().url("http://192.168.45.2:8080/ha").build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d("--------", "onFailure: "+e.getMessage());
}

@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Log.d("---------", "onResponse: "+response.body().string());
}
}
});


还有Http put形式的

public static void invoke() {
try {
String url = "http://xxxxxx";
HttpGet httpReq = new HttpGet(url);
httpReq.addHeader(BasicScheme.authenticate(
new UsernamePasswordCredentials("Hello", "123456"),
"UTF-8", false));
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse httpResponse = httpClient.execute(httpReq);
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpResponse.getEntity().getContent()));
for (String s = reader.readLine(); s != null; s = reader.readLine()) {
builder.append(s);
}
String result = builder.toString();
} catch (Exception e) {
e.printStackTrace();
}
}


HttpGet 在安卓API中已经过时,可以使用HttpUrlConnection

HttpPost

public static void getUserData() {
//1.创建 HttpClient 的实例
try {
//使用base64进行加密
//把认证信息发到header中
final String tokenStr = Base64.encode(("testclient" + ":testpass").getBytes());
HashMap<String, String> hashMap = new HashMap<String, String>();
String paramsStr = Utility.getHttpParamsStr(hashMap);
StringEntity stringEntity = new StringEntity(paramsStr);
stringEntity.setContentType("application/x-www-form-urlencoded");
HttpPost post = new HttpPost(API.loginCode);
post.setHeader("Content-Type", "application/json");
post.setHeader("Authorization", tokenStr);
HttpClient client = new DefaultHttpClient();
HttpResponse httpResponse = client.execute(post);
String result = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
Logger.i("--------invoke--", "ClientProtocolException " + e.getMessage());
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
Logger.i("--------invoke--", "IOException " + e.getMessage());
e.printStackTrace();
}
}


HttpPost也属于已过时API

public class HttpUtils {

/*
* Function  :   发送Post请求到服务器
* Param     :   params请求体内容,encode编码格式
*/
public static String submitPostData(String strUrlPath, Map<String, String> params, String encode) {
byte[] data = getRequestData(params, encode).toString().getBytes();//获得请求体
try {
URL url = new URL(strUrlPath);
Logger.i("-------getUserId---", "url " + url);
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
httpURLConnection.setConnectTimeout(3000);     //设置连接超时时间
httpURLConnection.setDoInput(true);                  //打开输入流,以便从服务器获取数据
httpURLConnection.setDoOutput(true);                 //打开输出流,以便向服务器提交数据
httpURLConnection.setRequestMethod("POST");     //设置以Post方式提交数据
httpURLConnection.setUseCaches(false);               //使用Post方式不能使用缓存
//设置请求体的类型是文本类型
httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
//设置请求体的长度
httpURLConnection.setRequestProperty("Content-Length", String.valueOf(data.length));
//获得输出流,向服务器写入数据
OutputStream outputStream = httpURLConnection.getOutputStream();
outputStream.write(data); //   data  实际就是 map中的key=value 拼接的字符串
final String tokenStr = "Basic " + Base64.encode(("Hello" + ":123456").getBytes());
httpURLConnection.addRequestProperty("Authorization", tokenStr);

int response = httpURLConnection.getResponseCode();            //获得服务器的响应码
if(response == HttpURLConnection.HTTP_OK) {
InputStream inptStream = httpURLConnection.getInputStream();
return dealResponseResult(inptStream);                     //处理服务器的响应结果
}
} catch (IOException e) {
//e.printStackTrace();
return "err: " + e.getMessage().toString();
}
return "-1";
}

public static StringBuffer getRequestData(Map<String, String> params, String encode) {
StringBuffer stringBuffer = new StringBuffer();        //存储封装好的请求体信息
try {
for(Map.Entry<String, String> entry : params.entrySet()) {
stringBuffer.append(entry.getKey())
.append("=")
.append(URLEncoder.encode(entry.getValue(), encode))
.append("&");
}
stringBuffer.deleteCharAt(stringBuffer.length() - 1);    //删除最后的一个"&"
} catch (Exception e) {
e.printStackTrace();
}
return stringBuffer;
}

/*
* Function  :   处理服务器的响应结果(将输入流转化成字符串)
* Param     :   inputStream服务器的响应输入流
*/
public static String dealResponseResult(InputStream inputStream) {
String resultData = null;      //存储处理结果
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] data = new byte[1024];
int len = 0;
try {
while((len = inputStream.read(data)) != -1) {
byteArrayOutputStream.write(data, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
resultData = new String(byteArrayOutputStream.toByteArray());
Logger.i("-------getUserId---", "dealResponseResult " + resultData);
return resultData;
}

}


  final String tokenStr = "Basic " + Base64.encode(("Hello" + ":123456").getBytes());

 httpURLConnection.addRequestProperty("Authorization", tokenStr);   

  就是设置  Authentication 的关键,是Base64把用户名,密码以 name:key 方式加密,然后再加到

 "Basic " 后面 ,二服务端会根据 Oauth框架进行解析,

以Php为例得到用户名字段是 PHP_AUTH_USER ,密码是 PHP_AUTH_PW。

推荐使用 HttpUtils方式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐