-
안드로이드 웹뷰에서 로그인 세션 유지하기Dev/android 2019. 5. 9. 15:53
하이브리드 앱은 간단히 말해 웹을 네이티브 앱으로 포장한 앱이다..
외부는 네이티브 단이고 핵심 기능은 웹에서 실행하기 때문에
ios나 안드로이드나 상관없이 웹만 수정하면 된다. 즉 유지보수가 용이한 장점이 있다.
오늘 해볼 것은 로그인은 네이티브에서 하고 쿠키 세션을 가지고 웹뷰로 넘어가서 로그인을 유지시키는 것이다.
그림으로 간단하게 그려봤는데 오히려 보기 어려울수도 있을것 같다..
네이티브 로그인 화면에서 아이디, 비밀번호를 입력 후 서버에 확인을 받으면 쿠키를 생성한다.
그 쿠키로 다시 url을 로드할 때 서버에 보내서 로그인 상태를 유지시킨다.
그러면 웹뷰에는 마치 웹에서 로그인한 것 처럼 로그인 성공시 보여줄 페이지가 로드된다.
activity_login.xml
1234567891011121314151617181920212223242526272829303132333435363738394041424344xmlns:tools="http://schemas.android.com/tools"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"><EditTextandroid: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" /><EditTextandroid: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" /><Buttonandroid: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로 돌아가서
1234567891011121314151617181920212223public class LoginActivity extends Activity {private EditText etPassword, etUsername;String passWord, userName;Button login;@Overridepublic 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
1234567891011121314151617181920212223package com.example.myapplication;import java.util.List;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 를 서버에 보내보자.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970private void loginCheck(final String userName, final String passWord) {class LoginAsync extends AsyncTask<String, Void, String> {private Dialog loadingDialog;@Overrideprotected void onPreExecute() {super.onPreExecute();}@Overrideprotected 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.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) {}result = sb.toString();} catch (ClientProtocolException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return result;}@Overrideprotected 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 ScripterloginCheck에서 id와 password를 매개변수로 받은 후 내부에 AsyncTask를 상속받는 LoginAsync 클래스를 정의했다.
onPreExecute() 에선 로딩중인 다이얼로그가 뜨고
doInBackground() 에서 HttpClient 에 POST 방식으로 아이디와 비밀번호를 전송한다.
서버는 인증 처리 후 결과 값을 response 에 전달하고 앱은 BufferedReader로 받아 확인한다.
여기선 로그인에 성공 하면 "OK" 가 회신된다.
onPostExecute() 에서 result로 "OK" 값이 오면 성공했다는 토스트 메시지를 보여주고
현재 HttpClient 에 cookie store에 쿠키가 비어있는지 확인 후 webViewActivity로 로그인할 주소값과 함께 Intent 한다.
webViewActivity.java에 해당하는 레이아웃을 만들어 주자.
activity_webview.xml
1234567891011<?xml version="1.0" encoding="utf-8"?>android:layout_width="match_parent"android:layout_height="match_parent" ><WebViewandroid: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그냥 웹뷰 하나 달랑 놨다.
123456789101112131415161718192021222324252627282930313233343536373839public class webViewActivity extends Activity {private WebView webView;@Overrideprotected 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을 로드하면 된다.
'Dev > android' 카테고리의 다른 글
Glide로 서버에서 이미지를 받아 MenuItem의 아이콘 변경하기 (비트맵으로 변경하기) (0) 2020.01.14 ImageView에서 background 와 src 의 차이 (0) 2019.12.16 OS버전 별 변경점 (0) 2019.08.16 Firebase Cloud Messaging (FCM / 푸시 알림) 사용하기 2 (0) 2019.05.09 Firebase Cloud Messaging (FCM / 푸시 알림) 사용하기 1 (0) 2019.05.09