我们都知道,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认证是很简单的,如下:

  1. //第一个参数为用户名,第二个参数为密码
  2. final String basic = Credentials.basic("zhangsan", "123456");
  3. OkHttpClient client = new OkHttpClient.Builder()
  4. .authenticator(new Authenticator() {
  5. @Override
  6. public Request authenticate(Route route, Response response) throws IOException {
  7. return response.request().newBuilder().header("Authorization", basic).build();
  8. }
  9. })
  10. .build();
  11. Request request = new Request.Builder().url("http://192.168.45.2:8080/ha").build();
  12. client.newCall(request).enqueue(new Callback() {
  13. @Override
  14. public void onFailure(Call call, IOException e) {
  15. Log.d("google.sang", "onFailure: "+e.getMessage());
  16. }
  17.  
  18. @Override
  19. public void onResponse(Call call, Response response) throws IOException {
  20. if (response.isSuccessful()) {
  21. Log.d("google.sang", "onResponse: "+response.body().string());
  22. }
  23. }
  24. });

在构建OkHttpClient的时候,有一个方法authenticator,该方法接收一个Authenticator对象,该对象中有一个authenticate方法,当我们发起一个网络请求的时候,如果服务端返回一个401错误码的时候,401表示未认证,这个时候系统就会调用该方法来获取用户信息并重新发起请求。这个信息是添加在Http协议头信息里边的,Authorization的值是一个字符串,但是这个字符串我们一般使用Base64对其进行编码,所以这里使用Credentials类中的basic方法来构建这个字符串,实际就是对字符串进行Base64编码。OK,由于OkHttpClient我们在使用的时候都会进行封装,所以这一块的代码只需要写一次就可以了,当我们发起一个网络请求的时候,我们来看看服务端要怎么处理:

  1. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  2. String header = request.getHeader("authorization");
  3. if (header != null) {
  4. String base64 = header.substring(6, header.length());
  5. byte[] bytes = Base64.decode(base64, Base64.DEFAULT);
  6. String userNameAndPasswd = new String(bytes, 0, bytes.length);
  7. if (userNameAndPasswd.equals("zhangsan:123456")) {
  8. PrintWriter out = response.getWriter();
  9. out.write("hello");
  10. System.out.println("认证成功");
  11. }else{
  12. returnError(response);
  13. }
  14. } else {
  15. returnError(response);
  16. }
  17. }
  18.  
  19. private void returnError(HttpServletResponse response) throws IOException {
  20. response.setStatus(401);
  21. PrintWriter out = response.getWriter();
  22. out.write("未认证");
  23. System.out.println("认证失败");
  24. }

先从请求头中获取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. bzoj 2595 [Wc2008]游览计划(斯坦纳树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2595 [题意] 给定N*M的长方形,选最少权值和的格子使得要求的K个点连通. [科普] ...

  2. [Java Code] 时间维度循环生成代码片段

    public static void main(String[] args) throws ParseException { String str = "20140301"; St ...

  3. Google App Engine Deployment 相关问题

    1.GAE instance上传成功之后可以正常运行的情况下.在Google账户中“关联的应用和网站”,撤销Google App Engine appcfg对Google账户的访问权限. 再次上传时, ...

  4. Oracle Database 12c 新特性 - Pluggable Database

    在Oracle Database 12c中,可组装式数据库 - Pluggable Database为云计算而生.在12c以前,Oracle数据库是通过Schema来进行用户模式隔离的,现在,可组装式 ...

  5. HDU-4749 Parade Show KMP算法 | DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4749 题意:给两个串S和P,求S串中存在多少个与P串的大小关系一样的串. 因为数字的范围是1<= ...

  6. RabbitMQ (三) 发布/订阅 -摘自网络

    这篇博客中,我们会做一些改变,就是把一个消息发给多个消费者,这种模式称之为发布/订阅(类似观察者模式). 为了验证这种模式,我们准备构建一个简单的日志系统.这个系统包含两类程序,一类程序发动日志,另一 ...

  7. HDU 1702 队列与栈的简单运用http://acm.hdu.edu.cn/showproblem.php?pid=1702

    #include<stdio.h> #include<string.h> #include<queue> #include<stack> #define ...

  8. 从 ALAsset 中取出属性

    #pragma mark - 从相册数组中取出所有的 图片数据 -(NSMutableArray *)getImageFromAlbumArray:(NSArray *)albumArr { NSMu ...

  9. POJ 3237 Tree (树链剖分 路径剖分 线段树的lazy标记)

    题目链接:http://poj.org/problem?id=3237 一棵有边权的树,有3种操作. 树链剖分+线段树lazy标记.lazy为0表示没更新区间或者区间更新了2的倍数次,1表示为更新,每 ...

  10. HDU 3687 National Day Parade (暴力)

    题意:给定 n 个人,在 n 列,问你移动最少的距离,使得他们形成一个n*n的矩阵. 析:这个题本来是要找中位数的,但是有特殊情况,所以改成暴力了,时间也很短,就是从第一个能够放左角的位置开始找,取最 ...