개요 사용자의 인증이 필요한 웹 사이트마다 로그인 기능을 필요로 한다면 민감한 정보에 대한 관리가 필요해지기 때문에 번거로울 수 있고, 보안에 취약해질 수 있다. 따라서 google이나 naver, kakao같은 외부 소셜 서비스를 기반으로 회원가입/로그인 할 수 있는 기능을 많이들 사용하고는 하는데, 이를 위해 접근 권한을 위임받은 것을 OAuth라고 한다. OAuth를 사용하지 않고 소셜 서비스에 인증을 위임하기 위해서는 사용자는 소셜 서비스의 인증을 위한 수단을 서버에 위임해야 했다. 이는 소셜 서비스 외부로 ID/PW(인증)가 노출되게 되는 문제가 있다. 이렇게 서버가 사용자의 인증을 필요로 하는 이유는 소셜 서비스로의 인가를 필요로 하는 것이 목적이므로, 인증은 사용자에 직접 위임하고, 인가는..
애플리케이션 서비스를 개발할 때 데이터는 DB에 보관하고, DB와의 연결을 위해서 애플리케이션(클라이언트)은 애플리케이션 서버를 이용하여 DB와의 연결을 구축했다. 이 연결은 구축된 커넥션을 통해서 sql을 전달하면 db에서 결과를 응답받는 식으로 진행되었는데, 문제는 DB의 종류마다 이 커넥션의 방법이 달라서 DB를 변경하면 애플리케이션 서버의 DB관련 코드도 변경해주어야 했다는 것이다. 이러한 불편함을 해소하기 위해서 JDBC라는 자바 커넥션 표준이 등장하게 된다. JPA의 구현체인 hibernate도 내부적으로 이러한 JDBC를 사용하여 DB와 통신한다. JDBC (Java DB Connectivity) JDBC는 자바에서 데이터베이스에 접근하기 위한 API들을 제공하는 라이브러리로, 연결-SQL ..
개요 CI/CD (Continuous Integration/Continuous Delivery, Continuous Deployment)란 애플리케이션 개발 단계를 자동화하여 애플리케이션을 짧은 주기로 고객에게 제공하는 절차를 말한다. 그 과정에서 코드를 병합하고 build/test하고 서버로 옮기는 과정이 반복되게 되는데, 이러한 반복 작업을 줄이는 것이 CI/CD이다. CI: 지속적인 통합 CI는 애플리케이션 코드의 변경을 정기적으로 build/test하는 과정을 자동화한 것을 말한다. 즉 애플리케이션 코드의 새로운 변경사항이 자동으로 공유 리포지토리에 병합된다.1. 개발자가 구현한 코드를 기존 코드와 병합한다.2. 병합된 코드가 올바르게 동작하고 빌드되는지 검증한다.3. 검증 결과 문제가 있..
개요 스프링을 사용할때 기본적으로 JPARespository를 이용하여 DB에 대한 쿼리 메소드 기능을 사용하게 된다. 하지만 기본적인 CRUD기능이 아니라 더 복잡한 쿼리문을 작성하기 위해서는 네이티브 쿼리를 작성하거나, jpql을 사용해야 했다. https://eckrin.tistory.com/37 [JPA] 객체지향 쿼리 언어(JPQL) 0. 소개 DB에 접근하기 위해서는 기본적으로 쿼리문이 실행되어야 한다. jpa를 이용하면 기본적인 SQL문이 자동으로 나가게 되긴 하지만, 직접 쿼리문을 작성하여 쿼리를 보내야 할 때를 위해 SQL을 eckrin.tistory.com 하지만 jpql을 작성할 경우, 쿼리문이 복잡해질수록 쿼리 스트링이 길어지게 되고, jpql 문자열 자체에 오타 혹은 문법적인 오류..
스프링 시큐리티와 jwt를 이용하여 api를 개발할때, 사용자의 정보를 제대로 전송하기 위해서는 크게 @AuthenticationPrincipal 어노테이션을 이용하여 인증이 필요한 요청마다 SecurityContextHolder에 저장한 인증값을 가져오는 방법도 있고, HandlerMethodArgumentResolver를 이용하여 토큰에서 인증값을 가져오는 클래스를 직접 만드는 방법이 있다. @AuthenticationPrincipal 사용하기 @AuthenticationPrincipal 어노테이션을 사용하면 UserDetailsService의 loadUserByUsername을 통해서 return한 객체(UserDetails)를 파라미터로 직접 받아서 사용할 수 있다. @PostMapping("/c..
자바스크립트는 자바를 이용한 서버 사이드 스크립트 언어이다. 따라서 스크립트 태그 내의 자바 소스코드를 컴파일하고, 나머지는 html로 간주하여 처리한다. 클라이언트가 JSP 요청을 하면, 서버에서 JSP 컨테이너를 통해 전달받은 jsp파일을 서블릿을 통해서 java파일로 변환하고 컴파일해서 클래스 파일을 생성한다. 이 클래스 파일은 메모리에 로딩 하여 실행된 이후, 그 결과는 html형태로 가공되어 응답되며, 웹 브라우저는 그것을 클라이언트에 표시한다. 스크립트 태그 - JSP 페이지에서 자바 코드를 삽입할 수 있는 부분. JSP컨테이너는 스크립트 태그 부분을 제외한 나머지 부분을 html등의 일반 텍스트로 간주 - 과 같이 사용한다. 선언문 : 자바 변수나 메소드를 정의할 때 사용한다. 스크립틀릿 :..
저번에 HTML 페이지를 이용한 에러 처리를 공부했다. https://eckrin.tistory.com/entry/Spring-MVC-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC [Spring MVC] 스프링 HTTP 에러 처리 기본 예외처리 자바의 경우, 예외가 발생했을 때 그 예외를 별도로 처리해주지 않는다면 해당 메소드를 호출한 상위 스택에 예외를 던지고, main에 이르러서까지 예외가 처리되지 않는다면 정 eckrin.tistory.com API 예외처리 그런데 앱 서버를 만드는 등 HTML을 사용할 수 없고 API를 사용해야 하는 경우에는 어떻게 해결할 수 있을까? 이 경우 HTML 오류 페이지를 만드는 단순한 방법으로는 ..
기본 예외처리 자바의 경우, 예외가 발생했을 때 그 예외를 별도로 처리해주지 않는다면 해당 메소드를 호출한 상위 스택에 예외를 던지고, main에 이르러서까지 예외가 처리되지 않는다면 정보를 출력하면서 main 쓰레드가 종료된다. 비슷하게 웹 애플리케이션의 경우 사용자 요청별로 별도의 쓰레드가 할당되어 서블릿 컨테이너 안에서 실행되는데, 애플리케이션에서 발생한 에러를 서블릿 안에서 처리하지 못하고 바깥으로 전달되면 톰캣과 같은 WAS(Web Application Server)까지 예외가 전달된다. 그러면 WAS는 서버에서 처리할 수 없는 오류가 발생한 것으로 생각해서 HTTP 500 error를 발생시킨다. 커스텀 서블릿 오류 화면 설정 설정 이전에 에러시 Whitelabel 화면을 띄워주지 않도록 에러..
서블릿 필터 일반적으로 웹 서비스에서, 로그인을 해야 들어갈 수 있는 페이지들이 존재한다. 서블릿 필터가 없다면 이러한 기능을 위해서 각각의 컨트롤러에서 클라이언트가 알맞은 권한을 지녔는지 확인하고, 기능 추가시마다 별도로 필터를 추가해주어야 한다. 서블릿 필터는 클라이언트로부터 서버로 요청이 들어오면 서블릿(스프링이라면 Dispatcher Servlet으로 이해) 실행 직전에 필터링해준다. 권한O 사용자 : HTTP 요청 -> 서블릿 컨테이너 -> 필터 -> 서블릿 -> 컨트롤러 권한X 사용자 : HTTP 요청 -> 서블릿 컨테이너 -> 필터(적절하지 않은 요청이라 판단, 서블릿 호출X) 이러한 필터는 하나 이상으로 구성될 수도 있다. 필터 사용필터를 사용하려면 Filter 인터페이스를 구현하고, 설..
순수한 스프링 시큐리티에 jwt를 사용하여 클라이언트-서버 통신에 권한 인가(Authorization) 기능을 추가해보자. 먼저 스프링 시큐리티는 보안을 담당하는 프레임워크로, 세션 체크, auth redirect(로그인 완료시 다음화면 전환)과 같은 기능을 수행해준다. 의존성 추가 가장 먼저 jwt토큰을 만들어주는 라이브러리를 gradle에 추가해주자. //시큐리티 implementation("org.springframework.boot:spring-boot-starter-security") //jwt //implementation("io.jsonwebtoken:jjwt:0.9.1") implementation("io.jsonwebtoken:jjwt-api:0.11.5") implementation("..
세션+쿠키 로그인 일반적으로 웹에서 서버로 url을 통해 요청하면, 서버에서는 적절한 컨트롤러가 매핑하고 내부 로직등을 통과한 후 뷰(html 등)를 리턴해준다. 이 때 (세션 만료 후)최초 요청시 헤더 쿠키를 이용하여 세션 id를 발급한 후 사용자 정보도 같이 저장하고, 이후 요청마다 서버의 세션 저장소에서 쿠키의 세션id를 확인하여 자동으로 사용자 인증과 함께 세션 만료 여부도 확인한다. (https://eckrin.tistory.com/entry/Spring-MVC-%EC%BF%A0%ED%82%A4%EC%84%B8%EC%85%98%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8) JWT? 그렇다면 왜 세션 로그인 방식이 아닌, Js..
UserDetails 스프링 시큐리티에서 사용자의 정보를 담는 인터페이스이다. 하지만 대부분의 경우 기본 UserDetails 인터페이스로는 구현에 한계가 있기 때문에 다음과 같이 UserDetails를 구현하여 사용한다. 스프링 시큐리티는 로그인 요청을 가로채서 인가처리를 하는데, 기존 UserDetails 대신 그것을 구현한 객체를 저장,관리하게끔 하자. UserDetails를 구현한 객체(PrincipalDetails)를 만들고, UserDetailsService를 구현한 객체(PrincipalDetailsService)에서 그것을 저장하면 시큐리티가 커스텀한 UserDetails를 사용하여 관리해주는 것 같다. //스프링 시큐리티가 로그인 요청을 가로채서 UserDetails를 구현한 객체를 저장..