我们都知道,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开发中的使用的更多相关文章

  1. android开发中的5种存储数据方式

    数据存储在开发中是使用最频繁的,根据不同的情况选择不同的存储数据方式对于提高开发效率很有帮助.下面笔者在主要介绍Android平台中实现数据存储的5种方式. 1.使用SharedPreferences ...

  2. Android开发中怎样调用系统Email发送邮件(多种调用方式)

    在Android中调用其他程序进行相关处理,几乎都是使用的Intent,所以,Email也不例外,所谓的调用Email,只是说Email可以接收Intent并做这些事情 我们都知道,在Android中 ...

  3. 怎样在Android开发中FPS游戏实现的两种方式比较

    怎样在Android开发中FPS游戏实现的两种方式比较 如何用Android平台开发FPS游戏,其实现过程有哪些方法,这些方法又有哪些不同的地方呢?首先让我们先了解下什么是FPS 英文名:FPS (F ...

  4. Android开发中常用的ListView列表的优化方式ViewHolder

    在Android开发中难免会遇到大量的数据加载到ListView中进行显示, 然后其中最重要的数据传递桥梁Adapter适配器是常用的,随着市场的需 求变化ListView'条目中的内容是越来越多这就 ...

  5. Android学习探索之Java 8 在Android 开发中的应用

    前言: Java 8推出已经将近2年多了,引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时减化了各种设计模式的实现方式,是Java有史以来最重要的更新.但是Android上, ...

  6. 在android开发中使用multdex的方法-IT蓝豹为你整理

    Android系统在安装应用时,往往需要优化Dex,而由于处理工具DexOpt对id数目的限制,导致其处理的数目不能超过65536个,因此在Android开发中,需要使用到MultiDex来解决这个问 ...

  7. Android开发中的问题及相应解决(持续更新)

    最近博客写的少了,以后还得经常更新才行. ------------------------------------------------------------ 1.特定业务需求下try cath ...

  8. 关于Android开发中的证书和密钥等问题

    关于Android开发中的证书和密钥等问题 引言 除了Android发布应用签名时需要用到证书外,在进行google Map Api开发和Facebook SDK API开发等时都需要申请API Ke ...

  9. Android开发中,那些让您觉得相见恨晚的方法、类或接口

    Android开发中,那些让你觉得相见恨晚的方法.类或接口本篇文章内容提取自知乎Android开发中,有哪些让你觉得相见恨晚的方法.类或接口?,其实有一部是JAVA的,但是在android开发中也算常 ...

随机推荐

  1. LyX转Word

    写毕业论文是一件非常繁锁的事情,一大堆的图片.公式都要往上贴,有时弄不好就把编号搞错了,有时可能没注意,一不小心字体格式.版面格式又全乱了.怎么办?--其实这只是在word环境下才会有的烦恼. 对于w ...

  2. HTML5每日一练之input新增加的六种时间类型应用

    今天介绍一下input在HTML5中新增加的时间类型的应用,与昨天的练习一样,如果在以下这几种输入框中输入的格式不正确,也是无法提交的. 注意:此种类型的input在Opera10+中效果为佳,Chr ...

  3. Spark SQL应用

    Spark Shell启动后,就可以用Spark SQL API执行数据分析查询. 在第一个示例中,我们将从文本文件中加载用户数据并从数据集中创建一个DataFrame对象.然后运行DataFrame ...

  4. AutoCAD.NET二次开发:创建自定义菜单的两种方法比较

    目前我已经掌握的创建CAD菜单方法有两种: COM方式: http://www.cnblogs.com/bomb12138/p/3607929.html CUI方式: http://www.cnblo ...

  5. [iOS基础控件 - 6.10.3] DatePicker & UIToolBar

    A.需求 1. 学习DatePicker的基本配置 2.使用TextField召唤指定类型的输入键盘View,这里使用DatePicker 3.给输入键盘上方加上一个UIToolBar,实现如关闭键盘 ...

  6. Light oj 1197 - Help Hanzo (素数筛技巧)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1197 给你a和b求a到b之间的素数个数. 先在小区间素数筛,大区间就用类似素数筛的想法 ...

  7. Python3爬取百度百科(配合PHP)

    用PHP写了一个网页,可以获取百度百科词条.源代码已分享至github:https://github.com/1049451037/xiaobaike/tree/master 那么通过Python来爬 ...

  8. 解决Linux下sqlplus中文乱码问题

    错误现象:在windows下用其他工具访问oracle,确认中文正常显示.在Linux下使用sqlplus查询数据表中文内容出现乱码. 分析及解决:因为windows下正常,所以问题应出现在Linux ...

  9. Oracle数据库程序包全局变量的应用

    1 前言  在程序实现过程中,经常用遇到一些全局变量或常数.在程序开发过程中,往往会将该变量或常数存储于临时表或前台程序的全局变量中,由此带来运行效率降低<频繁读取临时表>或安全隐患< ...

  10. 理解Windows中的路由表和默认网关

    每一个Windows系统中都具有IP路由表,它存储了本地计算机可以到达的网络目的地址范围和如何到达的路由信息.路由表是TCP/IP通信的基础,本地计算机上的任何TCP/IP通信都受到路由表的控制. 理 ...