原文链接:https://futurestud.io/blog/android-basic-authentication-with-retrofit
本文是Retrofit系列文章的第二篇。本节介绍了 Retrofit 如何使用用户名/邮箱和密码集成认证功能。下面的列表显示了该系列的所有文章:

Retrofit 系列目录

  1. 开始创建android客户端[已翻译]
  2. Android上的基本认证
  3. Android上的令牌认证[已翻译]
  4. Android上的OAuth
  5. 多个 Query 参数使用同一名字[已翻译]
  6. 同步与异步请求[已翻译]
  7. 在请求体里发送对象[已翻译]
  8. 自定义一个响应转换器[已翻译]
  9. 添加自定义请求头
  10. 可选的 Query 参数
  11. 如何集成 XML 转换器
  12. 使用 Log Level 调试请求
  13. 如何上传文件
  14. Series Round-Up
  15. Retrofit 2 — 1.9 升级指南
  16. Retrofit 2 — 如何上传文件
  17. Retrofit 2 — Log 请求与响应
  18. Retrofit 2 — Android 上的 Hawk 认证
  19. Retrofit 2 — 简单错误处理
  20. 如何在 Retrofit 1 里使用 OkHttp 3
  21. Retrofit 2 — 图书更新发布庆典
  22. 提交表单数据 — Urlencoded
  23. 提交表单数据 — Urlencoded 使用FieldMap
  24. Retrofit 2 — 在 OkHttp 拦截器里管理请求头部
  25. Retrofit 2 — 如何给每一个请求添加 Query 参数
  26. Retrofit 2 — 使用QueryMap 添加多个 Query 参数
  27. Retrofit 2 — 如何在请求时使用动态 Url
  28. Retrofit 2 — Url 处理,分辨和解析
  29. Retrofit 2 — POST 和PUT 请求里的常量, 默认值和逻辑值
  30. Retrofit 2 — 如何下载文件
  31. Retrofit 2 — 取消请求
  32. Retrofit 2 — 重用分析请求
  33. Retrofit 2 — 如何在运行时修改 API Base Url
  34. 可选Path参数
  35. 如何刷新 Access Token
  36. Retrofit 2 — 如何提交文本请求体
  37. Retrofit 2 — 使用 Query 参数来分页
  38. Retrofit 2 — 使用 链接头和动态 Url 来分页(比如GitHub)
  39. Retrofit 2 — 使用范围头字段来分页 (比如 Heroku)
  40. Retrofit 2 — 转换器介绍
  41. Retrofit 2 — 添加并自定义 Gson 转换器
  42. Retrofit 2 — 实现自定义转换器
  43. Retrofit 2 — 只在开发环境里启用日志
  44. Retrofit 2 — 如何上传多个文件
  45. Retrofit 2 — Passing Multiple Parts Along a File with @PartMap
  46. Retrofit 2 — 模仿服务端响应基本概念
  47. Retrofit 2 — 模仿服务端响应自定义网络行为
  48. Retrofit 2 — 使用 @HeaderMap 定义动态请求头

在上一篇 开始创建android客户端, 我们创建了Android客户端的最初版本来进行API/HTTP请求. 我们将在上一篇创建的客户端基础上增加基本认证功能.
再次提醒, 如果有不理解的地方请阅读上一篇以了解更多.

集成基本认证

让我们升级 ServiceGenerator 类并且增加创建认证请求的方法. 下面的代码片段扩展了 ServiceGenerator 类. 我们增加了 Retrofit 1.9 的示范代码. 如果您使用的是 Retrofit 2, 请直接跳到第2段代码 :)

Retrofit 1.9

public class ServiceGenerator {    public static final String API_BASE_URL = "https://your.api-base.url";    private static RestAdapter.Builder builder = new RestAdapter.Builder()                .setEndpoint(API_BASE_URL)                .setClient(new OkClient(new OkHttpClient()));    public static  S createService(Class serviceClass) {        return createService(serviceClass, null, null);    }    public static  S createService(Class serviceClass, String username, String password) {        if (username != null && password != null) {            // concatenate username and password with colon for authentication            String credentials = username + ":" + password;            // create Base64 encodet string            final String basic =                    "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);            builder.setRequestInterceptor(new RequestInterceptor() {                @Override                public void intercept(RequestFacade request) {                    request.addHeader("Authorization", basic);                    request.addHeader("Accept", "application/json");                }            });        }        RestAdapter adapter = builder.build();        return adapter.create(serviceClass);    }}

Retrofit 2

public class ServiceGenerator {    public static final String API_BASE_URL = "https://your.api-base.url";    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();    private static Retrofit.Builder builder =            new Retrofit.Builder()                    .baseUrl(API_BASE_URL)                    .addConverterFactory(GsonConverterFactory.create());    public static  S createService(Class serviceClass) {        return createService(serviceClass, null, null);    }    public static  S createService(Class serviceClass, String username, String password) {        if (username != null && password != null) {            String credentials = username + ":" + password;            final String basic =                    "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);            httpClient.addInterceptor(new Interceptor() {                @Override                public Response intercept(Interceptor.Chain chain) throws IOException {                    Request original = chain.request();                    Request.Builder requestBuilder = original.newBuilder()                        .header("Authorization", basic)                        .header("Accept", "application/json")                        .method(original.method(), original.body());                    Request request = requestBuilder.build();                    return chain.proceed(request);                }            });        }        OkHttpClient client = httpClient.build();        Retrofit retrofit = builder.client(client).build();        return retrofit.create(serviceClass);    }}

新方法 (第2个)有两个参数: usernamepassword. 你也可以用 username 代表邮箱. 创建客户端的目的与第1个方法相同: 使用RestAdapter( Retrofit 2 中是Retrofit) 类来创建OkHttp 客户端, 用来做HTTP请求和响应处理.
不同之处在于: 我们使用了 RequestInterceptor ( Retrofit 2 中是Interceptor) 来设置此OkHttp客户端执行的任何HTTP请求的授权标头值. 但是这只有在提供usernamepassword参数的情况下才会执行. 如果你没有提供这两个参数给方法, 它将会创建跟第1个方法一样的客户端. 这也是我们可以在ServiceGenerator 类中简化第1个方法的原因.
在认证部分我们必须调整给定的用户名/邮箱和密码格式. 基本的授权需要这两个值用冒号分割拼接成字符串, 然后用 Base64 编码.
几乎每一个 webservice 和API都评估HTTP请求的Authorization头. 这就是为什么我们在头部域设置编码凭据. 如果你的客户端调用的webservice指定另一个头部域来存放用户凭据,只需要将头部域 Authorization 改为你需要的.
如果你想接收特定格式的服务器响应的话, Accept 头将派上用场. 在我们的例子中,我们想接收JSON格式的响应,因为 Retrofit 附带了 Google’s GSON 来序列化对象到 JSON 格式, 反之亦然.

使用

只需要像上一篇一样调用 ServiceGenerator 类的新方法. 比如, 假设我们定义了一个 LoginService 接口, 代码如下.

Retrofit 1.9

public interface LoginService {      @POST("/login")    User basicLogin();}

Retrofit 2

public interface LoginService {      @POST("/login")    Call basicLogin();}

上述接口只有一个方法: basicLogin. 此方法使用 User 类作为返回值, 除此以外不需要任何query 或者 path 参数.
现在你可以通过传送给定的凭据(username, password)来创建你的 HTTP 客户端 .

Retrofit 1.9

LoginService loginService =      ServiceGenerator.createService(LoginService.class, "user", "secretpassword");User user = loginService.basicLogin();

Retrofit 2

LoginService loginService =     ServiceGenerator.createService(LoginService.class, "user", "secretpassword");Call call = loginService.basicLogin();  User user = call.execute().body();

ServiceGenerator方法将创建HTTP客户端,包括定义的授权标头. 一旦你调用 loginServicebasicLogin方法 , 提供的凭据将自动传递到请求的API端点.

接下来做什么

接下来的文章介绍了如何实现 Retrofit 自定义 OAuth 客户端.
如果有任何问题或建议请 Twitter: @futurestud_io.

更多相关文章

  1. 箭头函数的基础使用
  2. NPM 和webpack 的基础使用
  3. Python list sort方法的具体使用
  4. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程
  5. Android(安卓)Jetpack-LiveDataBus使用
  6. [简略记录]android中使用javamail的问题
  7. Android程序员指南(0)
  8. 给Android开发者的Flutter指南 (下) [翻译]
  9. Android调用WebService之客户端实现(二)

随机推荐

  1. android 制作 ppm开机图
  2. android onLowMemory
  3. ffmpeg无损转h265
  4. Robotium_Automated UI testing for Andr
  5. android 无法安装ApiDemos的问题
  6. Android(安卓)访问外部存储设备 - getExt
  7. Android(安卓)build target list.
  8. Android(安卓)各种蓝牙UUID
  9. TexturePacker 使用
  10. Mobile, iPhone, Android市场前景分析