Retrofit — 用實現Basic Authentication

 

這是在一系列 Retrofit 文章的第二篇, 它介紹了怎麼在 Retrofit 裏集成 base authentication。

Retrofit 系列文章概覽

  1. 基礎入門
  2. 用 Retrofit 實現 Basic Authentication

基礎入門裏,我們創建了一個初始的 client 去執行 API/HTTP 請求。我們將上一篇文章裏創建的 client 爲基礎,然後在它上面擴展功能來進行 basic authentication。你也可以再次閱讀基礎入門去獲取更多關於創建 client 端的信息。

集成 Basic Authentication

我們先更新 ServiceGenerator 類然後創建一個方法在請求中添加 authentication header。下面的代碼片段擴展了上一篇文章 的 ServiceGenerator 類。在 Retrofit 1.9的代碼下面,我們添加了 Retrofit 2的示範代碼。如果你使用了新版本的 Retrofit,可以直接跳到下面看第二塊代碼:)

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("Acceppt", "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 httpClient = new OkHttpClient();
    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.interceptors().clear();
            httpClient.interceptors().add(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", "applicaton/json");
                        .method(original.method(), original.body());

                    Request request = requestBuilder.build();
                    return chain.proceed(request);
                }
            });
        }

        Retrofit retrofit = builder.client(httpClient).build();
        return retrofit.create(serviceClass);
    }
}

 

這個新的 createService 方法多了兩個參數:username 和 password。username 也可以使用 email。創建 client 的基本過程與原來相同:使用 RestAdapter (在Retrofit2裏使用 Retrofit )類創建一個 OkHttp client 去處理所有的 http 請求和響應。

不同的地方在於: 我們用 RequestInterceptor (在Retrofit2裏使用 Interceptor )爲每一個通過這個 OkHttp client 的 http 請求設置 Authorization header。但是這個只有在提供 username 和 password 的情況下才會做。如果你不提供 username 和 password ,它將會創建一個和上篇文章裏一樣的 client 。因此我們可以簡化 ServiceGenerator 類的第一個方法。

對於認證部分,我們必須調整給定的 username/email 和 password 的格式。Basic authentication 要求把這兩個值組成一個用冒號分隔的字符串,然後把這個新組成的字符串用 Base64 編碼。

幾乎所有的 webservice 和 API 驗證 Authorization header,因此我們把編碼後的內容放到它裏面,如果你調用的webservice指定了另一個header field來獲取內容,你只要調整 Authorization 爲它指定的 field

如果你想從服務器收到一個指定格式的響應,那麼 Accept header 是必需的,在我們的例子裏,我們想要JSON格式的響應,既然 Retrofit 已經使用 GSON 來把服務端的響應轉成我們需要的類型。

使用

只需調用 ServiceGenerator 類的新的方法,就像在基礎入門文章裏那樣。首先我們定義一個 LoginService 。

Retrofit 1.9

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

Retrofit 2

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

上面的接口只有一個方法: basicLogin 。它有一個 User 類型的返回值,並且它不需要額外的 query 或 path 參數。

現在你可以傳遞你的認證信息 ( username, password ) 來創建一個 HTTP client 。

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<User> call = loginService.basicLogin();  
User user = call.execute().body(); 

ServiceGenerator 裏面的方法會自動創建含有認證信息 HTTP client,只要你調用 loginService 的 basicLogin 方法。你提供的認證信息會自動的發送給後端API。

參考資源

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章