본문 바로가기

Study/Android

Retrofit Okhttp3 Interceptor를 이용해 쿠키 유지하기

대부분의 앱을 개발하다보면 10의 9은 로그인 기능이 들어간다.

로그인 유지를 위해서는 클라이언트는 쿠키, 서버는 세션을 이용하게 된다.

안드로이드에서 쿠키 저장하는 방법은 CookieStore가 있는데 이것은 앱을 다시 실행하면 새로운 쿠키를 생성해서 다시 로그인 해야 하고 그러면 매번 로그인을 해줘야 하는 번거로운 작업이 생긴다.

실제로 사용하고 있는 앱 중에서 이러한 앱이 있는데.. 이건 개발자를 때리고 싶ㄷ............

 

찾아보다가 Okhttp를 이용하여 실행 시마다 항상 같은 쿠키값을 유지하는 방법이 있어 포스팅을 하게 되었다.

구현 방법은 말로 설명하면 아주 간단.

 

쿠키 가져옴 -> sharedPreferences에 저장 -> request 시 sharedPreferences에 저장해 둔 쿠키 가져와서 header에 추가해서 전달

 

package com.sample;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

public class MemoryInterceptor implements Interceptor {
    private Context context;

    public MemoryInterceptor(Context context) {
        this.context = context;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Request.Builder requestBuilder = request.newBuilder();
        String printUrl = convertNumericValue(request.url().encodedPathSegments());

        Log.i("MemoryInterceptor", "printUrl : "+printUrl);
        SharedPreferences preferences = context.getSharedPreferences(MemoryUtils.PREFERENCES, Context.MODE_PRIVATE);


        // cookie 가져오기
        Set<String> getCookies = preferences.getStringSet("cookies", new HashSet<>());

        // cookie 셋팅
        for (String cookie : getCookies) {
            requestBuilder.addHeader("Cookie", cookie);
        }
        Response setResponse = chain.proceed(requestBuilder.build());


        // cookie를 SharedPreferences에 넣어주기
        Response getResponse = chain.proceed(chain.request());
        if (!getResponse.headers("Set-Cookie").isEmpty()) {
            HashSet<String> cookies = new HashSet<>();
            for (String header : getResponse.headers("Set-Cookie")) {
                cookies.add(header);
            }
            // Preference에 cookies를 넣어주는 작업을 수행
            SharedPreferences.Editor editor = preferences.edit();
            editor.putStringSet("cookies", cookies);
            editor.commit();

            return getResponse;
        }
        
        return setResponse;
    }

    private String convertNumericValue(List<String> encodedPathSegments) {
        StringBuilder stringBuilder = new StringBuilder();
        for (String encodedPathSegment : encodedPathSegments) {
            encodedPathSegment = encodedPathSegment.replaceAll("^[0-9]{1,}$", "*");
            stringBuilder.append("/" + encodedPathSegment);
        }
        return stringBuilder.toString();
    }
}

 

필요한데로 나눠 쓰면 될 듯..