zoukankan      html  css  js  c++  java
  • 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的简单使用,有问题欢迎留言讨论。


    以上。


  • 相关阅读:
    AGC037F Counting of Subarrays
    AGC025F Addition and Andition
    CF506C Mr. Kitayuta vs. Bamboos
    AGC032D Rotation Sort
    ARC101F Robots and Exits
    AGC032E Modulo Pairing
    CF559E Gerald and Path
    CF685C Optimal Point
    聊聊Mysql索引和redis跳表
    什么是线程安全
  • 原文地址:https://www.cnblogs.com/lenve/p/6063852.html
Copyright © 2011-2022 走看看