관리 메뉴

나만을 위한 블로그

[Android] Volley 사용 시 com.android.volley.noconnectionerror java.io.ioexception cleartext http traffic to 'ip 주소' not permitted 에러 해결 본문

Android

[Android] Volley 사용 시 com.android.volley.noconnectionerror java.io.ioexception cleartext http traffic to 'ip 주소' not permitted 에러 해결

참깨빵위에참깨빵 2020. 1. 30. 20:41
728x90
반응형

참고한 사이트 : https://developside.tistory.com/85

 

안드로이드 http 프로토콜 접속 시 예외발생 조치 (ERR CLEARTEXT NOT PERMITTED)

어제 앱을 개발 중 glide v4를 사용하여 웹에 있는 그림을 load 하였는데, 아래와 같은 예외를 주며 동작을 하지 않았습니다. com.bumptech.glide.load.engine.GlideException: Fetching data failed, class java...

developside.tistory.com

안드로이드에서 제공하는 HTTP 통신 라이브러리 중 하나인 Volley를 써서, MySQL에 접근해 회원가입 기능을 만들기 시작했다.

만들고 테스트하던 도중 이런 에러가 떴다.

 

com.android.volley.noconnectionerror java.io.ioexception cleartext http traffic to '퍼블릭 IPv4 주소' not permitted

 

그리고 레트로핏에서도 이런 비슷한 에러가 떴다.

 

retrofit:RetrofitError: Cleartext HTTP traffic to '퍼블릭 IPv4 주소' not permitted

 

그래서 이 에러 하나만 잡으면 레트로핏이랑 Volley 쓸 수 있겠다, 라는 생각이 들어 곧바로 구글링했다.

해결법은 생각보다 너무 간단했다.

 

1. 현재 앱 안에서 사용 중인 HTTP 주소를 HTTPS로 변경(HTTPS를 적용시키려면 SSL을 공부해야 함)

2. 서버에서 아직 HTTPS로 구성돼 있지 않다면 어쩔 수 없이 HTTP로 써야 한다. 그렇다고 손가락 빨고만 있을 순 없으니 안드로이드 스튜디오 프로젝트의 res/xml 폴더에 아래와 같은 XML 파일을 만들어서 특정 주소를 허용하게 한다.

xml 파일 안에 123.456.789라고 쓰여진 부분이 있는데, 이곳에는 AWS 사용 중이라면 퍼블릭 IPv4 주소를 써넣고, 가상 머신을 쓴다면 아마 localhost 혹은 자신의 IP 주소를 쓰면 되지 않을까 생각한다.

 

res/xml/network_security_config.xml

 

<?xml version="1.0" encoding="utf-8"?>
  <network-security-config>
    <domain-config cleartextTrafficPermitted="true">
      <domain includeSubdomains="true">123.456.789</domain>
	</domain-config>
  </network-security-config>

 

그리고 매니페스트 파일의 application 안에 이 xml 파일을 config 파일로 지정한다.

난 맨 위에다 박아줬다. 이것으로 Volley에서 생기는 에러를 해결했다.

 

3. 2번은 위에서 말했듯 특정 주소를 허용 가능하게 설정하지만 그렇지 못한 상황도 있을 수 있다.

특정 사이트 또는 특정 이미지 경로를 외부에서 가져오는 경우가 그렇다. 그러면 모든 경로에서 허용되도록 설정해준다.

 

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>

 

4. 매니페스트의 application 태그 안에 usesCleartextTraffic 속성을 true로 박아준다. 이것으로 레트로핏에서 생기는 에러를 해결했다. 내 경우는 희한하게 Volley에선 해결됐는데 레트로핏은 또 다른 방식으로 해야 되더라.

 

 

그런데 왜 이렇게 귀찮게해야 할까?

안드로이드 9.0 파이 버전에서는 HTTP가 아닌 HTTPS를 사용하도록 강제한다.

 

출처 - https://developers-kr.googleblog.com/2018/08/introducing-android-9-pie.html

자세한 내용은 아래의 디벨로퍼 주소에서 확인. 아니면 접은글에 일부 문장을 구글 번역 플러그인으로 번역해 놨으니 관심있다면 읽어보자.

스크롤을 중간 쯤으로 내리면 사정상 HTTP를 써야 하는 사람들을 위해 해결 가이드라인을 제시해둔 문단과 코드가 있다.

 

https://android-developers.googleblog.com/2018/04/protecting-users-with-tls-by-default-in.html

 

Protecting users with TLS by default in Android P

Android is committed to keeping users, their devices, and their data safe. One of the ways that we keep data safe is by protecting all data that enters or leaves an Android device with Transport Layer Security (TLS) in transit. As we announced in our Andro

android-developers.googleblog.com

 

더보기

Android는 사용자, 기기 및 데이터를 안전하게 유지하기 위해 노력하고 있습니다.

데이터를 안전하게 보호하는 방법 중 하나는 전송 계층 보안 (TLS)을 사용하여 Android 디바이스에 들어가거나 나가는 모든 데이터를 전송하는 것입니다.

Android P 개발자 미리보기에서 발표 한 바와 같이 Android P(안드로이드 파이)를 대상으로하는 앱이 기본적으로 암호화되지 않은 연결을 허용하지 못하도록 하여 이러한 보호 기능을 더욱 향상시키고 있습니다.

이는 실수로 암호화되지 않은 연결을 방지하기 위해 Android Marshmallow에 android : usesCleartextTraffic manifest 속성을 도입했습니다.

Android Nougat에서는 앱이 암호화없이 네트워크 트래픽을 보내지 않을 것임을 나타낼 수 있는 네트워크 보안 구성 기능을 생성하여 해당 속성을 확장했습니다.

Android Nougat 및 Oreo에서는 일반 텍스트 연결을 계속 허용했습니다.

...모든 연결에 TLS를 사용해야하지만 일부 서버에 연결하는 등 레거시 이유로 일반 텍스트 트래픽을 사용해야 할 수도 있습니다. 이렇게하려면 해당 연결을 허용하도록 앱의 네트워크 보안 구성을 변경하십시오. 몇 가지 구성 예가 포함되었습니다. 좀 더 도움이 필요하면 네트워크 보안 구성 설명서를 참조하십시오.

 

내 핸드폰 기종이 갤럭시 S8+인데 안드로이드 9.0 파이 버전이었는지, 아니면 무심결에 업데이트해서 파이 버전으로 업그레이드 된 것인진 모르지만, 아무튼 파이 버전에서 앱을 빌드해야 하니 이 에러는 꼭 해결해야 했다.

만약 자신의 핸드폰이 파이 미만 버전이라면 신경쓰지 않아도 될 이슈겠지만, 나중에 핸드폰을 바꾸게 되면 파이 버전으로 쓸테니 미리 알아두는 것도 좋겠다.

반응형
Comments