ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [iOS] 10주차 세미나 정리
    iOS 2022. 11. 28. 21:20

    [미션검사 및 피드백]

    • Trouble Shooting

    1. API 호출시) 파라미터로 넘겨야하는 API를 사용할때 파라미터로 스트링값을 넘기는 과정에서 에러가 난다면?

    서버의 응답을 받을때(JSON으로) 디코딩 하는 과정이 필요하고, 반대로 서버에 보낼때 인코딩 과정이 필요하다.

    ex) Alamofire로 서버통신을 한다면, 파라미터를 넘길때도 파라미터도 제이슨으로 인코딩되어야한다.

    즉, 응답을 인코딩 방식을 보낼때, JSONEncoding default 살펴보기!

     

    https://velog.io/@cooo002/ios-Alarmofire%EC%97%90-%EB%8C%80%ED%95%9C-%EB%82%B4%EC%9A%A9

     

    [ios] Alamofire에 대한 내용

    Alarmofire

    velog.io

    위 보이는 예제처럼 응답할때 파라미터도 JSONEncoding으로 변환해서 보내야 서버쪽에서 해독하고 인식함.

     

    2. 반대로 문자열을 url로 인코딩할때 문제가 생기는 경우도있다.

    파라미터를 넘기거나 url을 구성할때 그 구성에 스트링값이 들어가거나 특수문자가 들어가는 경우가있을텐데, 스트링도 마찬가지로 인코딩 되야하는 작업이 있을때가 있음. (스트링을 파라미터로 보낼때, 문자열이 깨지지않도록 하는 작업이 필요!)

     

    https://ios-development.tistory.com/880

     

    [iOS - swift] URL encoding (addingPercentEncoding) 개념, (URL 인코딩 nil, 한글 인코딩, 띄어쓰기 인코딩)

    addingPercentEncoding 개념 일반적인 인코딩을 시도할 때 내부적으로 지정된 Set을 참고하여 인코딩하지만, Set에 없는 문자 (한글, 띄어쓰기)와 같은 것들을 %인코딩된 문자로 인코딩 시도 String to URL

    ios-development.tistory.com

    → 위 블로그도 참고해서 시도 

    위 예시처럼 url에 한글이 들어가는 경우?

    이게 url로 변환되는 경우 깨질수도있다.

    - 이 문자열을 url로 변하는 과정에서 문제가 생기지않게 해준다!

     

    3. http통신을 하는 과정에서 에러가 생기는경우?

    이런 경우는 스위프트가 보안상의 이유로 에러를 발생시키는 경우라고 볼 수 있다. 이러한 경우는 info.plist에서 설정을 변경하면 된다.

     

    https://doqtqu.tistory.com/107

     

    [iOS] App HTTP 접근 허용하기

    ATS(App Transport Sercurity)는 iOS 9 버전 이후부터 적용된 보안 정책으로, 보안에 취약한 네트워크를 차단시킨다.따라서 HTTP 접근 시 Console 창에 다음과 같은 에러가 발생하며 안내사항과 같이 Info.plist

    doqtqu.tistory.com

    스위프트에서 막아둔 http 통신을 설정하는것! (위 블로그 참고)

     

    + 참고 : 이미지 처리 대중적인 라이브러리 (kingfisher)

    이미지처리 과정에서 캐시나 이미지로드를 편리하게 가꿔놓은 라이브러리로 이미지처리, 이미지 캐싱할때 활용할 수 있다!

     

    라이브러리를 사용할때는 최소한 이 라이브러리가 어떠한 원리로 동작하는지 이해해줘야한다!

    [Token과 Login]

    • 소셜 로그인 미션을 해보며, 아래 로그인 화면은 익숙할텐데, 로그인은 사실 앱서비스의 첫번째 단계이다.

    • 로그인 이후에 진행되는 여러 기능들이나 서비스가 제공하고자 하는 기능들이 많이 있을건데, 로그인은 기본중의 기본이므로 로그인하고 이후의 과정이 더 중요하다!

    그 과정에서 생각해볼법한 내용! 

    - 앱을 사용할때, 로그인한 이후에 예를 들어 앱을 끄고 킬때, 로그인을 다시 하지않고 자동로그인이 되어있는 상태 (UserDefaults 이용) 

    - 그 외에 로그인 한 이후 마이페이지에 개인정보와 같은 데이터들이 보여질테고 또 다른 예시로는 커뮤니티앱은 작성한 게시물, 찜해놓은 게시물 등 이러한 데이터가 보여질것이다. 이러한 데이터가 보여지는 과정에서는 기본 전제조건이 우리의 개인정보를 바탕으로 가져오는 데이터다. 즉, 그 아이디에 맞는 데이터가 불러와질것임! 여기서 데이터가 불러와지는 과정에서 로그인 한번 더 하는 경우는 없다!

    개발자 입장에서 고려해보면, 마이페이지에 특정 유저의 데이터를 가져오는데 어떤 유저인지 따로 유저를 통해 따로 확인을 하지않음 (이게 가능한 이유에 대해! 배움 오늘!)

    : 로그인이 지속적으로 유지되고, 유저가 로그인한 그 정보가 유저의 디바이스에 어떻게 계속 저장이 되는지 그게 API를 통해서 어떻게 호출이 되는지를 알아볼것

    1. Cookie/Session
    2. JWT
    3. OAuth

    - 위 세가지 방식으로 로그인 정보가 유지된다!

     

    1. 쿠키, 세션 방식

    : 쿠키와 세션이 밀접한 관계가 있으므로 묶어서 부른다!

    쿠키란? 사용자가 삭제하지 않는 이상 계속 남아있으며 유저 정보를 저장한다. (구글 크롬을 켜서 설정탭에 들어가면 위 이미지처럼 쿠키라는 단어가 보인다!)
    • 크롬에서 쿠기를 삭제하게되면 어떤변화 일어나는지?

    : 구글이나, 네이버에서 로그인해두면 주로 지속적으로 로그인되어있을텐데, 쿠키를 허용해놓은 환경일때, 만약에 설정에 들어가서 쿠키나 캐시를 삭제하게된다면 자동으로 로그인이 풀려있는 모습을 볼 수 있다! 즉, 자동 로그인 혹은 유저의 정보를 저장하는것과 밀접한 관계가 있다는것을 알수있다

    로그인을 하는 과정과 로그인을 한 이후에 특정 과정들에 대해 나타낸 그림

    : 쿠키세션 방식을 통해 로그인이 이루어지고 데이터 축적되서 활용되는 방식

     

    1. 사용자가 로그인한다.

    2. 서버에서 회원DB를 통해 사용자를 확인한다.

    3. 회원가입이 되어있는 유저라면 로그인을 시키는 과정에서 세션 저장소(서버가 따로 들고있는 저장소 - 데이터베이스와 별개로)로 간다.

    4. 유저가 로그인한 정보를 바탕으로 서버는 세션 ID 발급한다.

    5. 세션 ID가 다시 사용자에게 응답으로써 넘어오게되어있다, 세션으로써 발급받은 아이디는 유저에게 쿠기로써 저장이 된다. -> 로그인이 정상적으로 완료가되었으면 쿠키에 세션 아이디가 저장


    여기서부터는 쿠키에 저장된 아이디가 어떻게 활용되는지에 대한 방식

    6. 로그인이 정상적으로 되면 유저의 고유정보를 바탕으로 다른 기능(이메일, 클라우드 등)을 사용할 수 있는데, 사용자가 쿠기에 저장해놓은 세션 ID가 있으니까 그 쿠키를 꺼내서 그걸 바탕으로 데이터 요청한다

    7. 서버입장에서도 아까 세션 ID를 발급했으니까 세션 ID만 확인하면, 즉 쿠기만 검증하면 따로 로그인할필요없이 그 사람을 식별할 수 있다.

    8. 사용자가 데이터, 혹은 API를 요청하면 쿠키에 저장된 세션 ID를 꺼내서 이걸 검증하는것이다. 즉, 이걸 바탕으로 어떤 유저가 어떤 요청을 하는거구나를 인식해서 회원 DB에 들어가서 검증할필요없이 바로 응답을 줄 수 있다. (유저 정보 획득)

     

    사용 이유는? 구현하기에 간단하고, 빠르게 구현해야 하거나 간단하게 로그인 해야한다면 해당 방식을 자주 활용한다.

    단점 : 쿠키같은건 괜히 공공 피씨나 누구나 접근할수있는 피씨에서 기록남기면 찝찝할수있다. 세션 아이디가 쿠키에 저장되는데, 세션 아이디 뿐만 아니라 접속했던 사이트들 등 다 저장되므로, 외부에 쿠키가 유출되거나 해커공격에 의해 쿠키가 변조되면 개인정보 유출도 되버림.

    즉, 외부유출로 인해 개인정보 유출이 크다!

     

    배우는 이유는? 뒤에 나올 JWT방식과 OAuth방식도 쿠키 세션 방식과 비슷하기때문이다.


    JWT 방식 : iOS 개발자라면 서버 개발자와 협업할때 로그인 과정에서 정말 많이 활용되는 방식이다. (반드시 기본 개념정도는 익혀야함)

     

    : 쿠키세션 방식과 매우 흡사하다.

     

    1. 서버에 포스트 API를 보내서 로그인 가능한 회원인지 살펴본다.

    2. 로그인 가능한 회원이라면 서버에서는 토큰을 발급해서 클라이언트한테 리스펀스로 반환해준다.

    3. 클라이언트는 토큰을 받아서 로그인이 된 상태이다.

    4. 이 토큰을 고유한 유저의 정보가 필요한 API를 호출할때마다 API 리퀘스트 헤더에 토큰을 담아둔 상태로 호출하게된다.

    5. 헤더를 열어보면 안에 토큰이 들어있으므로 헤더에 들어있는 토큰을 확인해서 어떠한 유저가 API를 호출했는지 식별할 수 있다.

    6. 식별된 유저의 API 호출을 받고 응답으로써 클라이언트에게 전달한다. (클라이언트가 요청한 00유저에 대한 정보를 리스펀스로 보내주는것)

    Cookie/Session과 JWT의 한가지 차이점이 있다면? Cookie/Session은 클라이언트에 저장된 쿠키를 꺼내서 보냈다면 JWT는 서버로부터 발급받은 토큰을 들고있다가 API 호출할때 토큰을 헤더에 집어넣는다는것

     

    + Token

    - JWT는 제이슨 포멧으로 이루어져있고, 토큰은 아래 첨부한 이미지처럼 고유한 문자열로 구성되어있다.

    토큰의 가장 큰 특징? 헤더, 내용, 서명 세가지 부분으로 나누어져있다.

    토큰은 길게 나열되어있고 점으로 구분되어있는걸 볼 수 있다.

    • 헤더(빨간색) : 이 부분은 토큰의 헤더 부분. JWT 토큰은 암호화 되어있다. 그래서 알수없는 긴 문자열로 나타나있음.

    이게 누구나 봤을때 어떤 내용인지 알수있으면 정보 유출의 위험이있으므로 암호화되어있다. 헤더는 암호화가 어떻게 되어있는지를 나타내는데, 특정 문자를 암호화할때 쓰는 암호화 방식을 담아둔게 헤더임! (어떤 방식으로 암호화가 되어있는지)

     

    • 내용(주황색) : 실질적인 데이터를 담고있는 부분.

    토큰의 유저의 아이디, 패스워드, 이름 등이 토큰에 담겨있다고 하면 그게 실질적으로 담기는 부분이다.

     

    • 서명(노랑색) : 내용이 변조되지않았는지, 바뀐 내용은 없는지 테스트하는 부분

    가운데에서 내용을 열어봤으니까 올바른 내용인지 확인하는 부분

    위처럼 실제로 토큰을 제이슨으로 해독해보면 JSON 형식으로 나와있는것을 볼수있음.


    마지막 OAuth 방식은 소셜로그인을할때 사용하는 로그인 방식으로 쿠키세션과 JWT 방식을 합쳐놓은 방식이다!

    첫번째는 쿠키세션 방식으로 진행되었다가 두번째는 JWT 방식으로 진행

    ex) 카카오 소셜 로그인

    - 아이디, 패스워드를 입력하는 과정이라고 하면 앱에 로그인이 아니라 카카오에 로그인을 하는것 (카카오가 제공하는 sdk를 통해 카카오에 로그인을 하는것)

    - 유저가 아이디, 패스워드를 입력하면 이걸 바탕으로 카카오에 들어있는 유저 디비를 통해서 이 카카오 아이디가 유효한지 일단 확인 (이 과정에서 로그인하고 클라이언트가 카카오에서 확인을 받은 로그인이된정보(세션아이디와 같은)를 발급받음)

    - 카카오에 유효한 아이디라는것을 확인한후 실질적으로 사용하는 로그인 API에 다시 감. 그러면 유저는 카카오에 로그인하고 카카오는 올바른 아이디라는것을 다시 클라이언트쪽에 넘기고 이 클라이언트가 카카오로부터 받은 인증을 바탕으로 서비스에 로그인하게되는것임.

    - 서비스에 로그인하면 JWT 토큰을 발급받음. 이후 과정은 JWT 방식과 동일하게 진행됨.

    첫번째는 쿠키세션방식으로 진행했다가 로그인에 성공하면 JWT방식으로 넘어가게 되는것임

     

    JWT 방식의 가장 큰 특징은 제이슨과 토큰이다!

     

    Token이란?

    실생활에서 사용하던 단어로, 토큰이라는것을 구입해서 지하철 개찰구에서 현금으로 토큰을 사고 그 토큰을 넣어 개찰구를 넘어갔음. 즉, 화폐처럼 활용되는 고유한 인증서같은것임.

    - 실생활에서 사용하던 단어

    고유한 유저의 정보를 인증해주는것, 즉 인증의 수단!

    - 토큰이 외부에 유출되면 개인정보가 유출되는것은 똑같다.

    - JWT 로그인방식이 대중적으로 활용되다보니 유저의 정보가 유출되는것을 방지하기 위해 다양한 방식이 도입되었다.

     

    JWT 방식은 로그인을 하면 토큰이 유출된다고 했는데데, 토큰이 유출되면 안되므로 만약에 유출되었을 경우를 대비하여 도입이 된게 토큰에 종류를 두었다! 

     

    Access 토큰, Refresh 토큰 두가지로! (두가지가 보안유지를 위해 중요한 요소로 작용됨)

     

    Access 토큰

    : 서버에 직접적으로 API를 호출할때 활용되는건 Access(접근하다) 토큰이다.

    • Access 토큰을 통해 API를 호출할때, 엑세스 토큰이 유출되면, 즉, 해커가 엑세스 토큰을 갈취하면 해커가 마음대로 API 를 호출할수있게되니까 유저의 개인정보가 유출되거나 변조될 확률이 크다. 이걸 대처하기위해 서버와 한가지 약속을 하게됨! Access 토큰에 유효기간을 두는것임! (한시간에서 하루정도!)
    • 다만 Access 토큰이 만료가 되버리면, 정상적인 유저도 Access 토큰을 쓸수없으므로 Refresh 토큰이 있는것임

    Refresh 토큰

    : 말그대로 업데이트, 즉 갱신하는 토큰

    • Access 토큰이 만료가 되었으면 Refresh 토큰을 통해 Access 토큰을 갱신하게된다! 
    • 올바른 유저라면 Access 토큰이 만료가 되었을때 Refresh 토큰을 통해 갱신을 하게된다!
    만약 Refresh 토큰도 만료가 된다면?

    Refresh 토큰도 3일에서 일주일정도 유효기간을 두어, Refresh 토큰도 만료가 되었다면 아예 강제로 로그아웃되게 구성을 해둠!

    (프로젝트시 JWT 방식으로 로그인구현을 하게될것이므로 이 흐름을 잘 이해해두면 좋다!)

     


    [기타 보충설명]

    1. Escaping Closure

    + 클로져라는 문법을 알고있다는 가정하에 설명 (클로저 개인적으로 공부하기!)

    클로저는 스위프트에서 1급 객체로 간주하기 때문에 함수의 파라미터로 넘길 수 있다!

    즉, 함수의 파라미터로써 클로저를 전달받을 수 있다.

    다만, 애플에서 자체적으로 파라미터로 넘겨받은 클로저는 함수 내부에서만 작동이 될수있게 막아놨다.

    이것을 탈출불가상태라고 부른다! (외부에 빼내거나 외부에서 호출할 경우 에러가 발생하게 된다.)

    이런식으로 클래스 내부에 프로퍼티로써 선언이 되어있을때, 만약에 변수로 선언되어있는 클로저를 함수에서 넘겨받은 파라미터로 대입하려고 하면 에러가 발생하게 된다. (컴파일러가 최적화하기 위해 애플에서 자체적으로 막아놨으므로)

    파라미터에 있는 클로저 앞에 @escaping이라는 키워드를 작성하게 되면 클로저가 탈출가능한 상태로 바뀌게된다. (에러가 사라지게된다.)

    위 예시코드에서 보면 변수로 선언되어있는 샘플클로저 변수가 아래있는 파라미터로 넘겨받은 콜백 함수로 대입이 가능하게 되는것임!

     

    어떠한 이점이 있는가? 탈출가능한 상태로 바뀐 클로저는 반드시 함수가 종료되기전에 실행되게끔 실행을 보장받게 되어있다!
    • 그렇다면 이게 왜 이점인지, 어떻게 활용되는지

    주로 서버 통신시 많이 활용

     

    서버통신시, API 호출할때 가장 큰 문제점은 API가 호출되는 시간이 존재하게 되는것이다. 서버 API는 네트워크가 필요하기때문에 와이파이 상태가 안좋으면 네트워크가 좀 느리다. 와이파이가 좋은곳에서 1초만에 호출되던게 와이파이가 안좋으면 5초나 걸린다.

    즉, API가 호출되는거를 함수가 보장을 하지않는다. 쉽게말하면, API 호출이 끝나기도전에 함수가 종료가 되버릴수가있다. 

     

    5초동안 기다렸다가 서버통신을 받아야하는데 함수가 못기다리고 1초만에 종료되버리면, 서버 호출이 완료가되지도않았는데 함수가 종료되버려서 유도했던대로 API 호출이 이루어지지않는것이다.

    이때, 이스케이핑 클로저를 활용하면 반드시 서버 API 호출이 완료가되는것을 보장하게된다. 

    실제로 작성되는 코드 예시

    1. 일반 클로저를 넘겨받을때랑 똑같은데, @이스케이핑이라는 키워드가 붙음

    2. 서버통신을 통해 서버 리스폰스를 받은것을 매핑해서 데이터 가져옴

    3. 이 데이터를 가공해서 써야하는데, 쓰려면 외부에 내보내야한다. 이스케이핑 클로저에 담아서 넘겨주면 해당 데이터를 사용할 수 있다. (탈출 가능하므로 함수 외부로 나갈 수 있다)


    [템플릿 안내]

    • Singleton 디자인 패턴

    클래스를 구현해서 여러가지 기능을 구현할때, 클래스는 여러 뷰 컨트롤러에서 공용으로 접근할 수 없는 요소이다. 클래스는 인스턴스화해서 사용해야한다.

     

    이렇게 사용하면 무슨 문제가 생기는지?

    뷰 컨트롤러가 여러개 있을때, 각각의 클래스는 인스턴스화 되어서 객체로써 다른 구현을 통해서 이루어져있기 때문에 동일한 정보를 가지고있지않음. (독립적인 객체로 구현)

     

    이 각각의 클래스가 공통된 클래스 인스턴스에 접근해야한다면 어떻게 구현해야하는지?

    대표적으로 회원가입할때 단계별로 회원가입한다면? 1단계에서는 아이디, 패스워드를 받고 2단계에서는이름과 연락처를 받고 이런식으로 유저의 정보를 나눠서 받을때가있는데, 결국에는 한가지 유저의 회원가입에 대한 과정이므로, 회원가입의 최종단계에서는 아이디, 이름, 전화번호 등 정보를 들고있다가 회원가입을 하는 API의 파라미터로 넘겨주는 경우가 많다.

    이런 경우에 활용될수있는게 각각 클래스가 독립적으로 존재하게 된다면, 한가지로 종합할 필요가있다. 이럴때 프로토콜 델리게이트 패턴을 쓰거나, 각 뷰컨트롤러에서 컨트롤러가 넘어갈때마다 데이터를 직접적으로 넘겨주거나 등의 과정을 거쳐야하는데 이런 방법은 비효율적이다.

    이럴때 효율적으로 활용할 수 있는게 Singleton 디자인 패턴이다 .

    클래스들이 독립적으로 이루어져있을때 한가지 고유한 객체로 구현해낼수있는 디자인 패턴
    • 각각의 뷰 컨트롤러들이 동일한 고유한 클래스 객체에 접근할 수 있는 디자인 패턴

    구현방식

    클래스내부에 스테틱, 스테틱 타입으로 자기자신의 프로퍼티를 가지는것이다.

    클래스의 이름은 userInfo인데, 이 클래스가 프로퍼티로써 자기자신의 클래스를 들고있는것

    • 이걸 배우는 이유는? 애플에서 기본적으로 제공하는 프레임워크도 싱글턴패턴이 굉장히 많이 활용되고 있다! (유저 디폴트 등등) 최소한 IOS 개발자라면 사용하지않더라도 개념정도는 알고있어야한다.

    드디어 세미나 끝! 10주간의 목표 잘 이루었는지 스스로 생각해보기 ~.~

     

Designed by Tistory.