2. Retrofit2 -- Basic Authentication on Android
2. Retrofit2 -- Basic Authentication on Android
上一节课中,我们创建了用于执行 API/HTTP 请求的原始 Android 客户端版本。本节课中,我们将使用上节课的客户端,对它进行增强,给它添加基本的认证功能。
整合基本的认证
首先,更新 ServiceGenerator 类,添加方法,用于把认证添加到请求上。下面的代码使用 1.9、2.0 版本分别进行了扩展:
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> S createService(Class<S> serviceClass) {
- return createService(serviceClass, null, null);
- }
- public static <S> S createService(Class<S> 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.0
- 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> S createService(Class<S> serviceClass) {
- return createService(serviceClass, null, null);
- }
- public static <S> S createService(Class<S> 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);
- }
- }
新方法中,多了两个参数:username 和 password。创建客户端的基本方法与老方法一样:使用 RestAdapter(2.0 版本是 Retrofit)类为所有的 HTTP 请求和响应处理创建 OKHttp 客户端。
新方法的不同在于:使用了 RequestInterceptor(2.0 版本是 Inteceptor)类来为 OKHttp 客户端执行的 HTTP 请求设置认证的头部。当然,只有提供了 username 和 password 参数,才会设置的。如果该方法没有接收到 username 和 password 参数,那么它创建的客户端与第一个方法相同。
关于验证部分,我们必须调整 username 和 password 的格式。基本认证请求把所有值当作一个以逗号分隔的多行索引字符串。此外,新创建的字符串必须是 Base64 格式的编码。
大多数的 webservice 和 API 都会对 HTTP 请求的认证头部进行计算。这就是为什么我们要把编码认证的值设置到头部。如果你调用 web 服务的客户端使用了其它的头部字段来接收用户的认证,那你应该把头部的 Authorization 转换为你服务所需的字段。
如果你想使用某种特定的格式来接收服务响应,那么,Accept 头部字段起着决定性的作用。在示例中,我们要求服务器返回的信息格式是 JSON。这是因为我们配置了 retrofit 使用 Google GSON 把序列化的对象和 JSON 互相转换。
用法
新方法的调用方法与上节课旧方法的调用方法一样。假定,我们定义了一个 LoginService:
Retrofit 1.9
- public interface LoginService {
- @POST("/login")
- void basicLogin(Callback<User> cb);
- }
Retrofit 2.0
- public interface LoginService {
- @POST("/login")
- Call<User> basicLogin();
- }
上面的接口只有一个方法:basicLogin。它的响应值类型是:User,没有其它的查询、或路径参数。
现在,我们创建一个客户端并把认证信息(username password)传入:
Retrofit 1.9
- LoginService loginService =
- ServiceGenerator.createService(LoginService.class, "user", "secretpassword");
- loginService.basicLogin(new Callback<User>() {
- @Override
- public void success(User user, Response response) {
- // user object available
- }
- @Override
- public void failure(RetrofitError error) {
- // handle errors, too
- }
- });
Retrofit 2.0
- LoginService loginService =
- ServiceGenerator.createService(LoginService.class, "user", "secretpassword");
- Call<User> call = loginService.basicLogin();
- call.enqueue(new Callback<User >() {
- @Override
- public void onResponse(Call<User> call, Response<User> response) {
- if (response.isSuccessful()) {
- // user object available
- } else {
- // error response, no access to resource?
- }
- }
- @Override
- public void onFailure(Call<User> call, Throwable t) {
- // something went completely south (like no internet connection)
- Log.d("Error", t.getMessage());
- }
- }
ServiceGenerator 方法将创建包含预定义认证头部的 HTTP 客户端。一旦调用 loginService 的 basicLogin 方法,提供的认证信息将自动被传入到请求的 API 端点。
2. Retrofit2 -- Basic Authentication on Android的更多相关文章
- Atitit HTTP 认证机制基本验证 (Basic Authentication) 和摘要验证 (Digest Authentication)attilax总结
Atitit HTTP认证机制基本验证 (Basic Authentication) 和摘要验证 (Digest Authentication)attilax总结 1.1. 最广泛使用的是基本验证 ( ...
- Nancy 学习-身份认证(Basic Authentication) 继续跨平台
开源 示例代码:https://github.com/linezero/NancyDemo 前面讲解Nancy的进阶部分,现在来学习Nancy 的身份认证. 本篇主要讲解Basic Authentic ...
- HTTP Basic Authentication
Client端发送请求, 要在发送请求的时候添加HTTP Basic Authentication认证信息到请求中,有两种方法:1. 在请求头中添加Authorization: Authoriz ...
- Web services 安全 - HTTP Basic Authentication
根据 RFC2617 的规定,HTTP 有两种标准的认证方式,即,BASIC 和 DIGEST.HTTP Basic Authentication 是指客户端必须使用用户名和密码在一个指定的域 (Re ...
- Web API 基于ASP.NET Identity的Basic Authentication
今天给大家分享在Web API下,如何利用ASP.NET Identity实现基本认证(Basic Authentication),在博客园子搜索了一圈Web API的基本认证,基本都是做的Forms ...
- PYTHON实现HTTP基本认证(BASIC AUTHENTICATION)
参考: http://www.voidspace.org.uk/python/articles/authentication.shtml#id20 http://zh.wikipedia.org/wi ...
- HTTP Basic Authentication认证的各种语言 后台用的
访问需要HTTP Basic Authentication认证的资源的各种语言的实现 无聊想调用下嘀咕的api的时候,发现需要HTTP Basic Authentication,就看了下. 什么是HT ...
- 一个HTTP Basic Authentication引发的异常
这几天在做一个功能,其实很简单.就是调用几个外部的API,返回数据后进行组装然后成为新的接口.其中一个API是一个很奇葩的API,虽然是基于HTTP的,但既没有基于SOAP规范,也不是Restful风 ...
- HTTP Basic Authentication认证(Web API)
当下最流行的Web Api 接口认证方式 HTTP Basic Authentication: http://smalltalllong.iteye.com/blog/912046 什么是HTTP B ...
随机推荐
- 在MySQL中使用子查询和标量子查询的基本用法
一.MySQL 子查询 子查询是将一个 SELECT 语句的查询结果作为中间结果,供另一个 SQL 语句调用.MySQL 支持 SQL 标准要求的所有子查询格式和操作,也扩展了特有的几种特性.子查询没 ...
- linux内核设计学习
负载平衡程序 load_balance调用条件:只要当前可执行队列为空,它就会被调用.被定时器调用:系统空闲时每隔1毫秒调用一次或其他情况下每隔200mm调用一次.单处理器不会被调用 执行步骤1. 首 ...
- Hadoop平台配置汇总
Hadoop平台配置汇总 @(Hadoop) Hadoop hadoop-env.sh和yarn-env.sh中export log和pid的dir即可和JAVA_HOME. core-site.xm ...
- (转)scala apply方法 笔记
在akka源码中有这样一个Cluster类. 使用方法是这样的:val cluster = Cluster(context.system); 作为scala菜鸟的我,并没有找到Cluster(syst ...
- WIN7如何替换开机登录画面
1 把你的图片保存为backgroundDefault.jpg,并确保和你的屏幕分辨率相同 2 把下面的代码另存为@开启自定义登录界面.reg(注意格式为ASCII格式) Windows Regist ...
- SOA服务总线设计
背景 基于总线的设计,借鉴了计算机内部硬件组成的设计思想(通过总线传输数据).在分布式系统中,不同子系统之间需要实现相互通信和远程调用,比较直接的方式就是“点对点”的通信方式,但是这样会暴露出一些很明 ...
- malloc、calloc、realloc的区别(转)
(1)C语言跟内存分配方式 <1>从静态存储区域分配. 内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量.static变量.<2> ...
- iOS UITableView表视图滚动隐藏UINavigationController导航栏
UITableView 继承于UIScrollView 所以UIScrollView 的代理方法相同适用于UITableView 中 隐藏导航栏的方法为: self.navigationControl ...
- 【DB2】不同编码格式下的汉字所占字节
UTF-8 (8-bit Unicode Transformation Format) 是一种针对Unicode的可变长度字符编码,又称万国码,它包含全世界所有国家需要用到的字符,是国际编码,通用性强 ...
- JavaScript Map 实现
//定义map function Map() { this.container = {}; } //将key-value放入map中 Map.prototype.put = function(key, ...