728x90

HttpURLConnection 에서 PHP 세션 헤더 정보를 추출하는 코드를 적어둔다.

완벽하게 완성된 코드를 만들려면 테스트가 좀 더 필요하다.

PHP 서버와 통신하기 위해 헤더 정보를 추출해서 통신하는 것이 꼭 필요한지 여부를 검토해야 한다.

일반적으로 이런 헤더가 없어도 통신하는데 전혀 지장이 없다.

다만, 보안문제에 더 완벽한 방법이 있을까 하는 측면에서 이런 저런 검토를 해보는 중이다.

http://link2me.tistory.com/1493 Android Asynchronous Http Client 코드와 비교해보는 것도 좋을 거 같다.

PHP 세션 헤더를 추출할 일은 없지만 서버와의 통신하는 코드가 더 편리한 것을 이용하면 될 거 같아서 이런 저런 코드 테스트 한 걸 적어둔다.


관련 코드

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.telephony.TelephonyManager;
import android.widget.Toast;

import com.google.firebase.iid.FirebaseInstanceId;
import com.tistory.link2me.common.AES256Cipher;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class Intro extends AppCompatActivity {
    Boolean loginChecked;
    public SharedPreferences settings;
    String loginID;
    String loginPW;
    String getDeviceID; // 스마트기기의 장치 고유값
    private static final String SESSION_COOKIE = "sessionid";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intro);

        // 네트워크 연결 검사
        if(NetworkConnection() == false){
            NotConnected_showAlert();
        }

        // 업그레이드 유무 검사

        // 자동 로그인 체크 검사
        settings = getSharedPreferences("settings", Activity.MODE_PRIVATE);
        loginChecked = settings.getBoolean("LoginChecked", false);
        if (loginChecked) {
            loginID = settings.getString("loginID", "");
            loginPW = settings.getString("loginPW", "");
            if(loginID != null && !loginID.isEmpty() && loginPW != null && !loginPW.isEmpty()){
                new AsyncLogin().execute(loginID,loginPW);
            } else {
                startActivity(new Intent(getApplication(), Login.class));
                finish();
            }
        } else{
            startActivity(new Intent(getApplication(), Login.class));
            finish();
        }

    }

    private  class AsyncLogin extends AsyncTask<String, Void, String> {
        ProgressDialog pdLoading = new ProgressDialog(Intro.this);
        HttpURLConnection conn;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            //this method will be running on UI thread
            pdLoading.setMessage("\tValidating user...");
            pdLoading.setCancelable(false);
            pdLoading.show();
        }

        @Override
        protected String doInBackground(String... params) {

            try {
                URL url = new URL(Value.IPADDRESS + "/loginChk.php");
                conn = (HttpURLConnection) url.openConnection();
                // 단말기의 ID 정보를 얻기 위해서는 READ_PHONE_STATE 권한이 필요
                TelephonyManager mTelephony = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
                if (mTelephony.getDeviceId() != null){
                    getDeviceID = mTelephony.getDeviceId();  // 스마트폰 기기 정보
                } else {
                    getDeviceID = Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ANDROID_ID);
                }

                // 사용자 기기의 고유 토큰 정보를 획득
                String getToken = FirebaseInstanceId.getInstance().getToken();

                System.out.println("userID : " + loginID);
                System.out.println("Input PW : " + loginPW);
                System.out.println("DeviceID : " + getDeviceID);
                System.out.println("Login Token : " + getToken);

                if(conn != null){ // 연결되었으면
                    conn.setConnectTimeout(10000); // milliseconds 연결 타임아웃시간

                    //add request header
                    conn.setRequestMethod("POST");
                    conn.setRequestProperty("USER-AGENT", "Mozilla/5.0");
                    conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                    conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
                    conn.setUseCaches(false);
                    conn.setDefaultUseCaches(false);
                    conn.setDoOutput(true); // POST 로 데이터를 넘겨주겠다는 옵션
                    conn.setDoInput(true); // 서버로부터 응답 헤더와 메시지를 읽어들이겠다는 옵션

                    // 전달할 인자들
                    params[0] = AES256Cipher.AES_Encode(params[0], Value.AES256Key);
                    params[1] = AES256Cipher.AES_Encode(params[1], Value.AES256Key);

                    Uri.Builder builder = new Uri.Builder()
                            .appendQueryParameter("loginID", params[0])
                            .appendQueryParameter("loginPW", params[1])
                            .appendQueryParameter("deviceID", getDeviceID)
                            //.appendQueryParameter("phoneVersion", Build.VERSION.RELEASE)
                            //.appendQueryParameter("phoneBrand", Build.BRAND)
                            //.appendQueryParameter("phoneModel", Build.MODEL)
                            .appendQueryParameter("tokenID", getToken);
                    String urlParameters = builder.build().getEncodedQuery();

                    DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
                    wr.writeBytes(urlParameters);
                    wr.flush();
                    wr.close();

                    int responseCode = conn.getResponseCode();
                    System.out.println("GET Response Code : " + responseCode);
                    if(responseCode == HttpURLConnection.HTTP_OK){ // 연결 코드가 리턴되면
                        // PHP 세션 헤더 정보 추출
                        String cookieTemp = conn.getHeaderField("Set-Cookie");
                        System.out.println("PHP Set-Cookie : " + cookieTemp);
                        if (cookieTemp.length() > 0) {
                            String[] splitCookie = cookieTemp.split(";");
                            String[] splitSessionId = splitCookie[0].split("=");
                            cookieTemp = splitSessionId[1];
                            SharedPreferences.Editor editor = settings.edit();
                            editor.putString(SESSION_COOKIE, cookieTemp);
                            editor.commit();
                            System.out.println("PHP SESSION_COOKIE : " + cookieTemp);
                        }
                        // 본문 정보 추출
                        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                        StringBuilder sb = new StringBuilder();
                        String line;
                        while((line = reader.readLine())!= null){
                            sb.append(line);
                        }
                        System.out.println("JSON Value : " + sb.toString().trim());
                        return sb.toString().trim();
                    }else{
                        return("unsuccessful");
                    }
                }

            } catch(Exception e){
                return new String("Exception: " + e.getMessage());
            } finally {
                conn.disconnect();
            }
            return null;
        }

        protected void onPostExecute(String result){
            pdLoading.dismiss();
            if(Integer.parseInt(result) > 0){ // 로그인 정보 일치하면 uid 정보를 받음
                System.out.println("uid value : " + result);
                SharedPreferences.Editor editor = settings.edit();
                editor.putString("idx", result);
                Toast.makeText(Intro.this,"로그인 성공", Toast.LENGTH_SHORT).show();
                startActivity(new Intent(getApplication(), MainActivity.class));
                finish(); // 현재 Activity 를 없애줌

            } else {
                startActivity(new Intent(getApplication(), Login.class));
                finish();
            }
        }
    }

    public void NotConnected_showAlert() {
        AlertDialog.Builder builder = new AlertDialog.Builder(Intro.this);
        builder.setTitle("네트워크 연결 오류");
        builder.setMessage("사용 가능한 무선네트워크가 없습니다.\n" + "먼저 무선네트워크 연결상태를 확인해 주세요.")
                .setCancelable(false)
                .setPositiveButton("확인", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        finish(); // exit
                        //application 프로세스를 강제 종료
                        android.os.Process.killProcess(android.os.Process.myPid() );
                    }
                });
        AlertDialog alert = builder.create();
        alert.show();
    }

    public boolean NetworkConnection() {
        int[] networkTypes = {ConnectivityManager.TYPE_MOBILE, ConnectivityManager.TYPE_WIFI};
        try {
            ConnectivityManager manager = (ConnectivityManager) getSystemService (Context.CONNECTIVITY_SERVICE);
            for (int networkType : networkTypes) {
                NetworkInfo activeNetwork = manager.getActiveNetworkInfo();
                if(activeNetwork != null && activeNetwork.getType() == networkType){
                    return true;
                }
            }
        } catch (Exception e) {
            return false;
        }
        return false;
    }
}



블로그 이미지

Link2Me

,