ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 안드로이드 웹뷰에서 로그인 세션 유지하기
    Dev/android 2019. 5. 9. 15:53

    하이브리드 앱은 간단히 말해 웹을 네이티브 앱으로 포장한 앱이다..

     

    외부는 네이티브 단이고 핵심 기능은 웹에서 실행하기 때문에

     

    ios나 안드로이드나 상관없이 웹만 수정하면 된다. 즉 유지보수가 용이한 장점이 있다.

     

     

    오늘 해볼 것은 로그인은 네이티브에서 하고 쿠키 세션을 가지고 웹뷰로 넘어가서 로그인을 유지시키는 것이다.

     

    그림으로 간단하게 그려봤는데 오히려 보기 어려울수도 있을것 같다..

     

     

     

    네이티브 로그인 화면에서 아이디, 비밀번호를 입력 후 서버에 확인을 받으면 쿠키를 생성한다.

    그 쿠키로 다시 url을 로드할 때 서버에 보내서 로그인 상태를 유지시킨다.

    그러면 웹뷰에는 마치 웹에서 로그인한 것 처럼 로그인 성공시 보여줄 페이지가 로드된다.

     

     

    activity_login.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="10dp"
    android:paddingTop="10dp"
    android:paddingRight="10dp"
    android:paddingBottom="10dp"
    tools:context=".LoginActivity">
     
     
    <EditText
    android:id="@+id/txtUsername"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="105dp"
    android:ems="10"
    android:hint="@string/hint_user"
    android:textSize="25sp" />
     
    <EditText
    android:id="@+id/txtPassword"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/txtUsername"
    android:layout_alignLeft="@+id/txtUsername"
    android:layout_marginTop="40dp"
    android:ems="10"
    android:hint="@string/hint_pwd"
    android:textSize="25sp" />
     
    <Button
    android:id="@+id/btnLogin"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/txtPassword"
    android:layout_alignLeft="@+id/txtPassword"
    android:layout_marginTop="28dp"
    android:text="@string/login_button"
    android:textSize="30sp" />
     
     
    </RelativeLayout>
     
    http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

     

     

     

    대충 로그인 UI를 만들어 봅시다

     

    그다음 LoginActivity.java로 돌아가서

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    public class LoginActivity extends Activity {
        private EditText etPassword, etUsername;
        String passWord, userName;
        Button login;
     
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_login);
     
            etUsername = (EditText) findViewById(R.id.txtUsername);
            etPassword = (EditText) findViewById(R.id.txtPassword);
            login = (Button) findViewById(R.id.btnLogin);
     
            login.setOnClickListener(new View.OnClickListener() {
                public void onClick(View arg0) {
                    userName = etUsername.getText().toString();
                    passWord = etPassword.getText().toString();
                    loginCheck(userName, passWord);
                }
            });
        }
    }
    http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

    이렇게 하면 onCreate() 에서 EditText 값을 받아서 login 버튼을 눌렀을 때, userName 와 passWord에 각각 아이디, 비밀번호가 저장될 것이다.

     

     

    먼저 HttpClient를 저장할 클래스를 생성한다

     

    SessionControl.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    package com.example.myapplication;
     
     
     
    public class SessionControl {
        static public DefaultHttpClient httpclient = null;
        static public List cookies;
     
        public static HttpClient getHttpclient() {
            if (httpclient == null) {
                SessionControl.setHttpclient(new DefaultHttpClient());
            }
            return httpclient;
        }
     
        public static void setHttpclient(DefaultHttpClient httpclient) {
            SessionControl.httpclient = httpclient;
        }
    }
     
    http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

     

    이후 LoginActivity.java 에서 loginCheck 메소드를 생성한다.

    로그인 버튼 리스너에서 전달 받을 userName, passWord 를 서버에 보내보자.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
     private void loginCheck(final String userName, final String passWord) {
            class LoginAsync extends AsyncTask<String, Void, String> {
                private Dialog loadingDialog;
                @Override
                protected void onPreExecute() {
                    super.onPreExecute();
                    loadingDialog = ProgressDialog.show(LoginActivity.this"Please wait""Loading...");
                }
     
                @Override
                protected String doInBackground(String... params) {
     
                    InputStream is = null;
                    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
                    nameValuePairs.add(new BasicNameValuePair("username", params[0]));
                    nameValuePairs.add(new BasicNameValuePair("password", params[1]));
             
                    String result = null;
     
                    try {
                        HttpClient httpClient = SessionControl.getHttpclient();
                        HttpPost httpPost = new HttpPost("http://서버에게 로그인 인증할 주소.co.kr");
                        httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                        HttpResponse response = httpClient.execute(httpPost);
                        HttpEntity entity = response.getEntity();
     
                        is = entity.getContent();
     
                        BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"), 8);
                        StringBuilder sb = new StringBuilder();
                        String line = null;
                        while ((line = reader.readLine()) != null) {
                            sb.append(line + "\n");
                        }
                        result = sb.toString();
     
     
                    } catch (ClientProtocolException e) {
                        e.printStackTrace();
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    return result;
                }
     
                @Override
                protected void onPostExecute(String result) {
                    String s = result.trim();
                    loadingDialog.dismiss();
                    if (s.equalsIgnoreCase("OK")) {
                        Toast.makeText(getApplicationContext(), "success", Toast.LENGTH_LONG).show();
                        SessionControl.cookies = SessionControl.httpclient.getCookieStore().getCookies();
                        if (!SessionControl.cookies.isEmpty()) {
                            Intent i = new Intent(getApplicationContext(), webViewActivity.class);
                            i.putExtra("myurl""http://로그인할 주소.co.kr");
                            startActivity(i);
                        }
     
                    } else {
                        Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();
                    }
                }
            }
     
            new LoginAsync().execute(userName, passWord);
     
        }
     
    http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

     

    loginCheck에서 id와 password를 매개변수로 받은 후 내부에 AsyncTask를 상속받는 LoginAsync 클래스를 정의했다.

     

    onPreExecute() 에선 로딩중인 다이얼로그가 뜨고

     

    doInBackground() 에서 HttpClient 에 POST 방식으로 아이디와 비밀번호를 전송한다.

    서버는 인증 처리 후 결과 값을 response 에 전달하고 앱은 BufferedReader로 받아 확인한다.

     

    여기선 로그인에 성공 하면 "OK" 가 회신된다.

     

    onPostExecute() 에서 result로 "OK" 값이 오면 성공했다는 토스트 메시지를 보여주고

    현재 HttpClient 에 cookie store에 쿠키가 비어있는지 확인 후 webViewActivity로 로그인할 주소값과 함께 Intent 한다.

     

    webViewActivity.java에 해당하는 레이아웃을 만들어 주자.

     

    activity_webview.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
     
    <WebView
        android:id="@+id/wv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></WebView>
     
    </RelativeLayout>
    http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

    그냥 웹뷰 하나 달랑 놨다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    public class webViewActivity extends Activity {
     
        private WebView webView;
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_webview);
            Intent intent = getIntent();
     
            String myUrlAddress = intent.getStringExtra("myurl");
            webView = findViewById(R.id.wv);
            webView.setWebViewClient(new WebViewClient());
            webView.getSettings().setJavaScriptEnabled(true);
            CookieManager cookieManager = CookieManager.getInstance();
            cookieManager.setAcceptCookie(true);
            List<Cookie> cookies = SessionControl.cookies;
            cookieManager.removeAllCookie();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    String cookieString = cookie.getName() + "=" + cookie.getValue() + "; Domain=" + cookie.getDomain();
                    cookieManager.setCookie(cookie.getDomain(), cookieString);
                   
                }
            }
           
            webView.loadUrl(myUrlAddress);
        }
     
        public void onResume() {
            super.onResume();
     
        }
     
        public void onPause() {
            super.onPause();
     
        }
    }
    http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

     

    웹뷰를 세팅해준다.

     

    여기서 CookieManager 를 사용하는데

    HttpClient에 생성된 쿠키 리스트들을 받아서 cookieManager에 setCookie 해준다.

    CookieManager 는 도메인으로 쿠키를 관리한다. 따라서 생성된 쿠키의 도메인을 쿠키 매니저에 꼭 넣어줘야 한다.

     

    cookieManager.setCookie(cookie.getDomain(), cookieString);

     

     

    그 다음 웹뷰에서 로그인할 url을 로드하면 된다.

     

     

Designed by Tistory.