수강이 제한됩니다.
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결백엔드 프레임워크 만들기
다섯번째 생각해볼 문제에 대한 제 생각입니다. 피드백 가능할까요?
벌써 제로님 강의의 수강률이 70%가 넘어가고있네요. 정말 재밌게 보고있습니다. 코드를 clone해오는 것은 실력이 안쌓인다 생각하여 깃허브에 코드를 직접 타이핑하면서 문제가 생기면 디버깅을 하면서 보고있다보니 진도가 느린 감도 없지 않아 있는거같네요. 그렇지만, 이번에도 코드를 직접 따라치고 디버깅을 하면서 전체적인 맥락을 계속 짚을 수가 있게 된거같습니다 :) 각설하고 제가 이번에 생각해볼 문제에 대한 생각은 다음과 같습니다. 1. 인증 정보는 세션에 저장됩니다. 하지만 세션을 사용할 수 없는 REST 같은 환경일 경우 인증정보를 획득할 수 있는 방법을 생각해보세요. JWT와 같은 서비스를 통해 토큰을 활용하여 인증정보를 획득할 수 있을 것 같습니다. 음 여기서 JWT에 대한 질문을 올려도 되는지 모르겠지만 KeyCloak 이나 Vault와 같은 걸로 토큰을 중앙 제어하는 것이 안전하다 들었습니다. 특히, 키클록은 인증/인가에 대한 많은 서비스를 제공해서 편리하다고 알고 있었는데 Access Token을 DB에 저장하는 것은 위험한지가 궁금하더라구요. 제가 현재 하는 사이드 프로젝트는 KeyCloak 도입은 아직 하지말자하고 테스트는 DB에서 진행 중인데 DB에 하면 위험한 행위일지? (액세스토큰 탈취 위험이 있기에..) 하지만 키클록이나 볼트도 동일하다고 생각하고 있기도 합니다.그렇다면 DB에 안전하게 액세스토큰을 저장하는 방법이 있을까요? 일단 만료시간을 최대한 짧게 해두고 리프레시토큰을 통해서 하고 있는데 이정도까지만해도 안전한지 궁금합니다. 또한, 토큰을 사용할 경우 Http header에 담는게 좋을지 아니면 POST request의 경우 Body에 담는 케이스도 경우도 있는데 https://datatracker.ietf.org/doc/html/rfc6750#section-2여길 보니 둘 다 해당 내용에 맞춰서 하면 별 문제 없는지도 궁금해졌습니다. 2. 인증과 접근제어를 통해 기밀성과 무결성을 보호하기 위한 벨 라파둘라와 비바 규칙을 알아 보세요.1. 벨 라파둘라 모델 - 기밀 정보에 대한 데미터 기밀성 및 통제된 액세스에 초점을 맞춘 모델로, 서브젝트와 오브젝트로 구분된다. 이 모델은 State-Machine의 개념을 기반으로 만들어졌으며, 컴퓨터 시스템에서 허용 가능한 상태 세트를 가지며 한 상태에서 다른 상태로 전환은 전환 기능에 의해서 정의된다. 이 모델은 두 개의 MAC 규칙을 정의한다. Simple Security Property : 더 높은 보안 수준의 개체를 읽을 수 없다. (No Read-Up) Star Secuirty Property : 낮은 보안 수준의 개체에 쓸 수 없다. (No Write-Down) 만약, 기밀, 비밀, 공개로 세 상태를 분류한다면 다음과 같다. 비밀 취급자는 자신의 상태보다 높은 기밀 파일과 자신의 상태와 동급인 비밀 파일을 만들 수 있으나, 공개 파일을 만들 수는 없으며, 비밀과 공개파일은 읽을 수 있으나 기밀 파일을 읽을 수는 없다. 한계점으로는 무결성을 파괴할 수 있다는 점이다. (낮은 레벨의 인가자가 상위 레벨의 문서를 변경가능하기 때문에) 2. 비바 모델 - 데이터의 무결성을 보장하기 위해 설계된 접근 제어 규칙을 작성하는 모델 델 라파둘라 모델("read down, write up")과 대조적으로 "read up, write down" 형식이며, 자신의 상태 이하의 파일을 만들 수 있으며, 자신의 상태 이상의 파일을 읽을 수 있다.따라서, 벨 라파둘라 모델과 다른 아래와 같은 규칙을 갖는다. Simple Security Property : 더 낮은 보안 수준의 개체를 읽을 수 없다. (No Read-Down) Star Secuirty Property : 높은 보안 수준의 개체에 쓸 수 없다. (No Write-Up) 이 두 모델은 처음 알게된 모델인데 벨 라파둘라 모델의 무결성 문제 때문에 비바모델이 나온 것으로 학습하였는데 사실 비바모델도 자기보다 높은 수준의 파일을 읽다보니 이것도 보안의 문제가 되지않나 궁금해지더라구요. 제로님의 생각은 어떠신지 궁금합니다! 3. 웹 브라우져에서 사용하는 쿠키는 WAS 에 유용한 정보를 제공합니다. 만약 쿠키가 3자에 노출되었을때 발생하는 문제점을 생각해보세요. 만약, 인증쪽에 쿠키를 사용하게 된다면 쿠키 스니핑과 같은 공격에 취약해질 수 있습니다. 이 쿠키정보를 토대로 로그인을 시도할 수 있는 문제도 발생한다고 생각합니다. 더 나아가 개인정보 침해의 문제가 있는데 사용자 이메일이나 브라우저 고유값 등과 같은 값이 포함되는 문제일 경우 이 사용자가 어떤 사이트를 접속했는지 그리고 접속한 사이트를 추정하여 연령대 및 성별 식별까지 가능하다고 생각합니다. 따라서, 개인정보보호를 위해서는 쿠키에 저장될 값은 최소화해야하며 개인정보나 그런 값들이 존재할 경우에는 난독화 혹은 https를 통해 모든 통신이 암호화되게끔 해야될 것 같습니다.
- 미해결백엔드 프레임워크 만들기
네번째 생각해볼 문제 제 생각을 적어보았습니다. 피드백 가능하실까요?
1. 비즈니스로직은 사용자 요구사항을 개발자가 코드로 구현한 산출물을 의미합니다. 비즈니스 로직을 재사용 할 수 있는 방법을 생각해보세요. 의존성 주입과 제어역전을 활용하여 비즈니스 로직을 재사용할 수 있습니다. 이 부분은 강의를 들으면서 따로 이해가 안가기도 했고 궁금하여서 좀 더 깊게 고민해봤는데, 토비의 스프링에서도 그렇고 다른 책들을 봐도 사실 프레임워크의 핵심은 DI와 IoC라는 것을 이해했고, 이번 챕터에 자세히 설명해주셔서 이해가 어느정도는 갔습니다. 그러나, DI와 IoC가 코드의 재사용을 한다는 부분이 100% 이해가 잘 안갔는데, 저희가 작성한 코드를 보자면 MasterController의 execute() 메서드를 통해 해당 키를 가져와서 그 키를 사용하는 이를테면 Emp001에 있는 select 메서드를 활용한다까지는 이해했습니다. 이 재사용성이라는게 그렇다면 이미 작성한 클래스의 메서드를 활용한다라고 이해하면될까요? 단순히 MasterController는 리플렉션을 통해 해당 클래스를 가져와서 메서드를 호출함으로서 컨트롤러에서 비즈니스 로직이 처리되는 것이 아니라 컨트롤러는 단순히 해당 키를 받아서 어떤 일을 처리하는지 위임하는 역할을 해주는지 궁금합니다. 2. 우리가 만든 프레임워크를 기준으로 IoC 흐름을 생각해보세요.위의 내용이랑 비슷한데 1. MasterController.execute() 메서드를 통해 키를 주입 2. 이때 MasterControllerD에서 해당 서비스에 대한 SQL 처리를 수행 2.1 SqlRunner().getSqlRuuner().getTable().getBox() 위와같은 체이닝을 통해 우리가 기존에 준비해둔 FW_SQL을 통해서 FW_CONTROLLER로 처리할 데이터 준비3. FW_CONTROLLER에서 넘어온 CLASS_NAME과 METHOD_NAME을 리플렉션을 통해 실제 수행이런 과정으로 되면서 MasterController는 키를 통해서 어떤 클래스의 메서드를 수행할 지 ControllerDao의 결과값을 통해서 가져온 후 실제 최종 수행은 리플렉션 invoke를 통해 해당 메서드를 수행하여 결과값을 리턴하는 식으로 돌아간다라고 이해했는데 맞을지 궁금합니다.
- 미해결백엔드 프레임워크 만들기
세번째 생각해볼 문제에 대한 제 생각입니다. 피드백 부탁드려도될까요?
1. 비즈니스로직에 SQL 이 섞이는 SQL 의존 문제를 해결하는 방법을 생각해보세요. 스프링 프레임워크의 `layered-architecture` 참고하자면, DB와 연관되는 부분들은 `Repository` 로 뺍니다. 이 부분을 흔히 `Repository Pattern` 이라 하는데 이렇게 함으로써 디비를 사용하는 쪽은 `Repository` 안에서 처리하고 비즈니스 로직은 해당 값을 온전히 쓰는식으로 개발하면 될 것 같습니다. 2. 한번 생성한 Connection 객체를 재사용해야 하는 이유를 생각해보세요. DB 연결과 같은 경우에는 계속해서 재사용하는 부분이기 때문에 싱글톤으로 둬서 재사용을 함으로써 시스템 자원을 효율적으로 다루기 위함. 3. DB 에 데이터를 저장할때 휴대폰 번호 같은 민감정보는 암호화를 해야 합니다. 암호화 기능은 어디에 구현해야 하는지 생각해보세요. 이 부분은 제 생각에는 Framework에서 실제 암호화가 필요한 부분을 사용하고자할 때 사용해야된다고 생각합니다. 저희 코드로 보면 `SqlRunner` 에서 `HP_N` 을 업데이트하는 부분에서 사용자에게 받은 `param` 을 담기 전에 암호화를 수행하고 담은 다음에 처리를 해야된다고 생각합니다. 그 이유는 일단, DB 함수로도 암호화 처리가 가능하지만 이는 코스트를 높기 때문에 최대한 이러한 처리는 암호화가 필요한 DB의 UPDATE나 INSERT 시에 처리하는게 맞다고 생각합니다. 이 부분에 대해서 제로님께서는 어떻게 생각하시는지 궁금합니다. 4. SQL 은 데이터를 가공하는 DML, 스키마를 정의하는 DDL 그리고 DB 를 제어하는 DCL 로 구분합니다. 그리고 우리가 만든 SQL 기능은 DML뿐만 아니고 DDL, DCL 도 사용 가능합니다. 하지만 WAS 에선 DDL 과 DCL 사용을 금지해야 하는데 이유와 해결방법을 생각해보세요. DDL, DCL을 사용하면 안되는 이유는 일단 웹어플리케이션 특성 상 불특정 다수가 사용할 수 있는 서비스들이 존재합니다. 이 때문에 만약 DDL 중에서도 `ALTER` 나 `TRUNCATE` 와 같은 치명적인 쿼리를 날릴 경우에 서비스 장애가 날 수 있다고 생각합니다. DCL같은 경우에는 트랜잭션 관련된 질의와 권한 관련 질의가 있는데 권한 질의 (REVOKE, GRANT)의 경우에는 만약 db 접속 권한이 넘어가게 될 경우에 서비스에 치명적인 구멍이 될 수 있다고 생각합니다. 또한, 트랜잭션 질의인 (COMMIT, ROLLBACK)도 기존에 우리가 만들었던 transaction의 기능과 혼동의 소지가 있다고 생각합니다. 이를 막기 위해서는 WAS에서 접속하는 DB 계정의 권한 설정을 `GRANT SELECT, UPDATE, DELETE, INSERT ON EMP TO db-user` 이런식으로 둬서 필요한 권한만 사용하게끔 하는 것이 좋다고 생각합니다. 5. 트랜잭션직렬성은 우선순위가 부여된 여러개의 트랜잭션이 동시에 병행/병렬수행되더라도 결과는 순서대로 실행됨을 의미합니다. 하지만 트랜잭션직렬성이 보장되더라도 트랜잭션이 서로 얽혀 종료가 안되는 데드락이 발생할 수 있는데 프레임워크에서 이를 해결할 수 있는 방법에 대해 생각해보세요. 이 부분이 이번 섹션에서 가장 어려웠던 질문이었던 것 같습니다. 저는 이 문제를 봤을 때 키워드 2개를 떠올렸습니다. 1. Transaction Propagation 2. Locking or Transaction Isolation-level 처음에는 2번이 뭔가 맞을 것 같았는데 프레임워크에서 이를 해결할 수 있는 방법이라 하셔서 1번같기도하고? (Spring은 Propagation 설정을 지원하니..) 뭔가 2번은 DB로 처리하는 부분이고, 이 설정은 Spring Data JPA에서만 지원하니 1번같다는 느낌을 받았습니다. 혹시 모르니 제 생각을 적어보겠습니다. 1번과 같은 경우에는 스프링에서는 기본 값이 `REQUIRED` 로 되어있는 것으로 알고 있습니다. 전 회사에서는 스프링 like한 자체 프레임워크를 사용했었는데 이러한 복잡한 부모 <-> 자식 트랜잭션간의 처리가 어렵다보니 TPS가 중요했던 서비스가 아니였어서 `REQUIRES_NEW` 처럼 항상 트랜잭션을 새로 생성하여 독립성을 보장하는 식으로 작업을 했었습니다. 이렇게 되면 각각의 트랜잭션들의 독립성이 보장되니 데드락같은 문제를 해결할 수 않을까 조심스럽게 생각해봤습니다. 2번과 같은 경우에는 라킹을 통해서 트랜잭션을 보장하는 부분이라고 볼 수 있습니다. 전파는 트랜잭션이 묶이게 할껀지 아니면 독립적으로 볼 지에 대한 내용이라면, 라킹은 동시성에 대한 내용이라고 생각합니다. mysql, mariadb는 `REPATABLE-READ` 가 기본값으로 세팅되어 있는데 조회된 내용이 항상 동일함을 보장할 수 있습니다. 그래서 제로님께서 해주신 질문의 의도는 데드락과 관련이 있고, 동시성과 관련이 있어보여서 이 부분이 좀 더 맞지않을까 생각이 드는데 잘 모르겠네요 ㅠㅠ 근데 이는 프레임워크에서 처리한다는 개념보다 뭔가 DB에서 설정하는 느낌이라 혹시 위의 2개가 아니라 다른 의도를 가지고 질문을 하셨던건지 궁금합니다. 번외. 현재 필요한 것 보다 과하게 제품을 디자인 하는 것을 오버엔지니어링 이라고 합니다. 우리가 개발시 사용하는 인터페이스클래스가 오버엔지니어링이 되는 경우가 있는데 이를 생각해보세요. 이 부분의 인터페이스 클래스가 정말 자바의 인터페이스를 뜻하는 건지 아니면 큰 개념의 인터페이스인지를 제가 이해를 못했어서 두 가지 모두 생각해보았습니다. 1. 자바의 인터페이스의 오버엔지니어링 케이스 이 경우에는 구현하려는 인터페이스에 너무 많은 메서드가 있는 경우라고 볼 수 있을 것 같습니다. 이를 테면 자동차의 `Tire` 라는 인터페이스가 존재하는데 타이어교체하기() 타이어공기압체크() 타이어크기() 타이어수명() 등.. 사용하지 않을 메서드들이 많은 경우에 오버엔지니어링이지 않을까 생각이 듭니다. 2. 소프트웨어 관점에서의 Interface 오버엔지니어링 케이스 소프트웨어 관점에서 보면 인터페이스는 아이폰으로 치면 볼륨업, 볼륨다운, 전원버튼과 같이 필요한 부분만 노출 시키고 내부 구현은 사용자에게 모르게끔 하는 부분이라고 볼 수 있습니다. 이러한 케이스의 오버엔지니어링 케이스는 사용자에게 필요 없는 정보까지 노출되거나 (캡슐화 위반) 사용자가 의도치 않게 쓸 수 있는 부분이 노출되어 있거나 (휴대폰으로 치면 이상한 버튼이 있는데 이걸 누르면 공장초기화가 된다던가?) 이러한 부분이라고 생각합니다. 지금까지의 예제에서는 현재는 SqlRunner가 `SQLiteJDBCTransaction` 을 사용하는데 실제 WAS 상에서 쓰기 위한 `SQLitePoolTransaction` 을 위한 코드들이 `SqlRunner` 상에 있습니다. 물론, 실제 사용될 코드이긴하나 만약 우리가 `SQLiteJDBCTransaction` 만 사용한다고 생각하면 이 부분이 오버엔지니어링이라 볼 수 있을 것 같습니다.중요한 점은 이는 확장을 위한 설계이기 때문에 만약에 확장이 안된다는 가정이 있어야할거같은데 약간 어거지로 지금까지 예제로 적어보았습니다 ㅎㅎ;
- 미해결백엔드 프레임워크 만들기
생각해볼 문제에 대한 제 생각입니다. 피드백 부탁드려도될까요?
- 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 1. 캡슐화를 위해서라고 생각합니다. 2. 이 부분을 제일 많이 고민했습니다. 자바8이 들면서 default 메서드까지 사용이 가능해지고, 상속보다 합성을 많이 사용하고 인터페이스를 자주사용하라는 얘기를 많이 들었습니다. 제가 처음에 생각했을 때는 Seralizeable 구현에 대한 문제와 serialVersionUID에 대한 값을 들고있어야하는 문제때문이라고만 생각했습니다.실제 인터페이스를 구현해서 따라가본 결과 다른 문제가 또 있었네요.바로, 저희가 구현한 BoxContext 내부에서 쓰레드로컬에 set할 떄 기존 코드에서는 BoxLocal과 BoxHttp에 분기를 태워서 실제 WAS 로딩시점에서는 BoxHttp가 쓰레드에 올라가고, 아닐 경우에는 BoxLocal이 올라가는데 이 두개를 처리하는 것을 인터페이스로 할 수 없음을 알게 되었습니다.즉, 마스터 컨트롤러에서 ThreadLocal에 적재를 할 때 상속으로 처리하지 않을 경우 컨트롤러에서 로직을 작성하여 이 경우에는 BoxLocal을 올리고, 아닐 경우에는 BoxHttp를 올리는 식으로 작업하게 되므로, 오히려 컨트롤러에 비즈니스 로직이 담기는 문제가 있다고 생각하게 됐습니다.이 부분이 맞을지 궁금하네요 ㅎㅎ;3. AOP 어노테이션은 가독성과 편리성 부여해줄 수 있다고 생각합니다. @Transactional 과 같은 어노테이션을 살펴보자면 원래는 try-catch로 TransactionManager를 처리하는 방식에서 @Transactional의 어노테이션을 붙여두면 명시적으로 이러한 try-catch의 중복되는 구문 없이 사용되는 것에서 생각하게 됩니다.뿐만 아니라 @Slf4j도 logger를 일일히 설정해서 중복되는 코드가 발생할 수 있는 부분을 어노테이션으로 단순화 시켜서 가독성과 편리성을 부여했다고 생각합니다.4. 이 부분이 제일 어려웠던 고민이였던 것 같습니다. 제 생각에는 톰캣의 동작원리는 ThreadPool을 생성하여 미리 쓰레드를 사용하고 생성하는 것을 알고 있습니다. 이 때문에 ThreadLocal은 GC의 대상이 안되므로 maxThreads 의 값이 넘어가면 뻗거나 혹은 문제가 생길거 같은데 이 부분은 제가 정확하게 몰라서 궁금한 부분이기도 합니다.TheadPool을 제가 잘 몰라서 그러는데 TheadPool에 쓰레드를 미리 만들어 두기 때문에 LocalThread 해제를 안할 시에 기존에 사용했던 쓰레드를 다시 재사용할 수 있으므로 이러한 문제가 있다고 생각해도 될까요?
- 미해결백엔드 프레임워크 만들기
try-catch-finally 문을 try-with-resource 문으로 변경할 수 있는 방법이 있을까요?
버퍼스트림이나 파일스트림같은 경우에는 자동으로 `try()` 내부에 선언되어 있을 경우 `close()`를 호출해주는 것으로 알고 있습니다. public static void main(String args[]) { try ( FileInputStream is = new FileInputStream("file.txt"); BufferedInputStream bis = new BufferedInputStream(is) ) { int data = -1; while ((data = bis.read()) != -1) { System.out.print((char) data); } } catch (IOException e) { e.printStackTrace(); } } 제가 궁금한 점은 TheadLocal.remove() 메서드가 위와같이 호출이 되는지와 만약 안되면 따로 이 처리에 대한 메서드를 구현시켜서 동작시켜야하는지가 궁금합니다.
- 미해결백엔드 프레임워크 만들기
sqllite 관련
안녕하세요 수강신청후 처음 질문드리는데요 sqlite-jdbc를 다운받으려고 하는데 강사님께서 백엔드 프레임워크를 만들기 위한 환경구성 강의에서는 sqlite-jdbc.jar sqlite-jdbc3.30.1.jar sqlite-jdbc3.30.1.source.jar 이렇게 세 개중 맨 위에거를 선택하셨는데 맨위에거랑 가운데 3.30이랑 차이가 있을까요? 저는 두번째거를 받아서 하려고 하는데 혹시 지장이 있을까요? 만약 맨 위에거를 해야한다면 어디서 다운 받을 수 있을까요? 강사님이 주신 링크에는 sqlite jar파일이 없는것 같아서요. 감사합니다.
- 미해결백엔드 프레임워크 만들기
첫 번째 실습 질문입니다.
1. 사전 설명 없이 갑자기 소스 코드 나오고 실습 돌리셔서 당황했습니다.. 그래도 첫 실습인데 어떻게 준비하면 좋을 지 안내 주셨으면 좋겠습니다.. 2. localhost:18080/waf/xxxxx?NAME=zero -> 요청된 리소스 [/waf/xxxxx]은(는) 가용하지 않습니다. 와 같이 오류가 발생합니다... 기초적인 내용이갰지만... 이 부분 뭐가 잘못 되었는지 모르겠습니다...ㅠㅠ web.xml에는 /waf/* 라고만 되어 있는데, 어떻게 MasterController를 찾아가는건가요..? xxxxx가 어떻게 맵핑이 되는지 모르겠습니다....