http协议Authorization认证方式在Android开发中的使用
我们都知道,http协议是一种无状态协议,在Web开发中,由于Session和Cookie的使用,使得服务端可以知道客户端的连接状态,即用户只需要在浏览器上登录一次,只要浏览器没有关闭,后续所有的请求服务端都会知道这个请求是谁发来的。但是在移动端开发的过程中,却是没有Session和Cookie,所以我们要想办法来解决这个问题。一般来说,在移动端开发想要解决这个问题有三种方案:
1.OAuth认证
2.Authorization认证
3.Cookie缓存
OAuth认证实际上就是使用令牌,这个有时间的话我们后文再说,第三种Cookie缓存则是模拟浏览器的方式,来把Cookie缓存到手机本地,可以存在sp中也可以存在数据库中,登录成功时候以后每次发起网络请求时带上这个Cookie,这样服务端就知道用户是否已经登陆了,不过这种方式在移动端开发中我们用的比较少,有的时候我们想要模拟网站登录,可以采用这个方式,关于Cookie缓存的用法可以参考使用OKHttp模拟登陆知乎,兼谈OKHttp中Cookie的使用!。
好了,今天我们就来看看Authorization这种认证方式的使用,本文主要介绍该种认证方式在OkHttp中的使用。假设服务端有一个收藏的接口,该接口的调用必须要先判断用户是否已经登录,但是我们不能在每一次接口调用的时候都携带上用户登录信息,这样太麻烦了,最好能有一种方式能够自动携带上这些东西,那就是Authorization认证。
在OkHttp中使用Authorization认证是很简单的,如下:
//第一个参数为用户名,第二个参数为密码
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("google.sang", "onFailure: "+e.getMessage());
} @Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
Log.d("google.sang", "onResponse: "+response.body().string());
}
}
});
在构建OkHttpClient的时候,有一个方法authenticator,该方法接收一个Authenticator对象,该对象中有一个authenticate方法,当我们发起一个网络请求的时候,如果服务端返回一个401错误码的时候,401表示未认证,这个时候系统就会调用该方法来获取用户信息并重新发起请求。这个信息是添加在Http协议头信息里边的,Authorization的值是一个字符串,但是这个字符串我们一般使用Base64对其进行编码,所以这里使用Credentials类中的basic方法来构建这个字符串,实际就是对字符串进行Base64编码。OK,由于OkHttpClient我们在使用的时候都会进行封装,所以这一块的代码只需要写一次就可以了,当我们发起一个网络请求的时候,我们来看看服务端要怎么处理:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String header = request.getHeader("authorization");
if (header != null) {
String base64 = header.substring(6, header.length());
byte[] bytes = Base64.decode(base64, Base64.DEFAULT);
String userNameAndPasswd = new String(bytes, 0, bytes.length);
if (userNameAndPasswd.equals("zhangsan:123456")) {
PrintWriter out = response.getWriter();
out.write("hello");
System.out.println("认证成功");
}else{
returnError(response);
}
} else {
returnError(response);
}
} private void returnError(HttpServletResponse response) throws IOException {
response.setStatus(401);
PrintWriter out = response.getWriter();
out.write("未认证");
System.out.println("认证失败");
}
先从请求头中获取authorization,如果authorization为null,表示移动端没有传递认证信息,这个时候返回错误码401,移动端收到401这个错误码之后就会添加上Authorization认证信息,再次发起网络请求,服务端收到请求后,先获取authorization认证信息,并去除掉前六个字符,前六个字符是Basic加一个空格,后面的字符就是Base64编码之后的字符串,对该字符串进行解码,解码之后进行判断用户名和密码是否正确,如果正确的话则返回一个认证成功。所以,当我们在移动端发起一个网络请求的时候,实际上服务端接收到了两个请求,打印日志分别如下:
这里小伙伴要注意的是如果你打算使用authorization来做认证,那么服务端一定要按规范开发,就是没有认证的时候返回的错误码必须是401.
OK,这就是Authorization的简单使用,有问题欢迎留言讨论。
以上。
http协议Authorization认证方式在Android开发中的使用的更多相关文章
- android开发中的5种存储数据方式
数据存储在开发中是使用最频繁的,根据不同的情况选择不同的存储数据方式对于提高开发效率很有帮助.下面笔者在主要介绍Android平台中实现数据存储的5种方式. 1.使用SharedPreferences ...
- Android开发中怎样调用系统Email发送邮件(多种调用方式)
在Android中调用其他程序进行相关处理,几乎都是使用的Intent,所以,Email也不例外,所谓的调用Email,只是说Email可以接收Intent并做这些事情 我们都知道,在Android中 ...
- 怎样在Android开发中FPS游戏实现的两种方式比较
怎样在Android开发中FPS游戏实现的两种方式比较 如何用Android平台开发FPS游戏,其实现过程有哪些方法,这些方法又有哪些不同的地方呢?首先让我们先了解下什么是FPS 英文名:FPS (F ...
- Android开发中常用的ListView列表的优化方式ViewHolder
在Android开发中难免会遇到大量的数据加载到ListView中进行显示, 然后其中最重要的数据传递桥梁Adapter适配器是常用的,随着市场的需 求变化ListView'条目中的内容是越来越多这就 ...
- Android学习探索之Java 8 在Android 开发中的应用
前言: Java 8推出已经将近2年多了,引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时减化了各种设计模式的实现方式,是Java有史以来最重要的更新.但是Android上, ...
- 在android开发中使用multdex的方法-IT蓝豹为你整理
Android系统在安装应用时,往往需要优化Dex,而由于处理工具DexOpt对id数目的限制,导致其处理的数目不能超过65536个,因此在Android开发中,需要使用到MultiDex来解决这个问 ...
- Android开发中的问题及相应解决(持续更新)
最近博客写的少了,以后还得经常更新才行. ------------------------------------------------------------ 1.特定业务需求下try cath ...
- 关于Android开发中的证书和密钥等问题
关于Android开发中的证书和密钥等问题 引言 除了Android发布应用签名时需要用到证书外,在进行google Map Api开发和Facebook SDK API开发等时都需要申请API Ke ...
- Android开发中,那些让您觉得相见恨晚的方法、类或接口
Android开发中,那些让你觉得相见恨晚的方法.类或接口本篇文章内容提取自知乎Android开发中,有哪些让你觉得相见恨晚的方法.类或接口?,其实有一部是JAVA的,但是在android开发中也算常 ...
随机推荐
- 在Toast里面显示图片
关于怎么在Toast里面显示图片,首先自定义一个toast,在自定义一个布局,这个布局你想让toast显示什么样的布局就定义什么样的,然后在自定的布局中放一个ImageView,在把自己自定义 ...
- The Datastore
[中央数据库模式难扩展]绝大多数的Web应用在处理一个为了以后的请求作检索用的请求时,需要存储信息.<1.Most useful web applications need to store i ...
- C# 释放非托管资源
C#中资源分为托管资源和非托管资源. 托管资源由垃圾回收器控制如何释放,不需要程序员过多的考虑(当然也程序员也可以自己释放). 非托管资源需要自己编写代码来释放.那么编写好的释放非托管资源的代码(释非 ...
- elasticsearch配置文件解析
配置es的集群名称 : cluster.name: fcz_es
- Spring+Quartz 整合一:常规整合
步骤一: 定时任务需要一个配置文件(spring-mvc-timeTask.xml 随便起名),将其在web.xml中加载 <context-param> <param-name&g ...
- UVALive 6910 Cutting Tree(离线逆序并查集)
[题目]:(地址:) http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97671#problem/E [题意]: 给出多棵树和两类操作:操作 ...
- inline(内联函数)
一般来说,调用函数会造成:目前的指令位置被存储下来,程序流跳转到所调用的函数,然后执行调用函数,最后跳转回之前存储的位置.对于需要常常调用的小函数来说,这会影响程序的运行效率.所以,c99新增了inl ...
- Webstorm2016激活码[ 转]
转至:http://blog.csdn.net/tingwode2014_/article/details/51063657 43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QT ...
- Hql处理日期格式化问题
1. Date date=Calendar.getInstance().getTime(); Date date1=Calendar.getInstance().getTime(); String h ...
- c#与java webservice调用问题
问题描述一: c#调用java写的websrevice,对方接收到的参数与实际传的值不一致,返回的时候值也获取不到,为null. 该参数为普通的string类型,因此不存在类型转换的问题. 处理: 使 ...