웹 인증.1(Cookie,Session,header)

ys·2024년 3월 1일

웹 인증

  • 웹 인증(Web Authentication) : 웹 어플리케이션에서 사용자의 정체성을 확인, 적절한 권한 부여하는 과정
  • 사용자가 누구인지 확인, 해당 사용자가 엑세스하려는 웹 리소스나 서비스에 대한 권한 확인
  • 웹 인증은, 웹 서비스의 보안성을 높이며
  • 사용자 데이터의 무단 접근을 방지하기 위한 중요한 보안 요소이다

로그인 인증

  1. ID/PW 기반 로그인
  2. 소셜 로그인(Oauth2)
  3. 이메일 인증
  4. 휴대폰 인증
  5. 다중 인증요소...등등등

Http Session

  • 웹 어플리케이션에서 사용자 정보를 저장하는 기술
  • http 프로토컬은 stateless 한 특성 때문에, 사용자가 요청을 보낼 때마다, 사용자 정보를 다시 전송해야 한다
  • 하지만 이러면, 통신에 대해 많은 리소스를 사용한다. ✅http session은 이런 문제를 해결하기 위해서 사용자 정보를 서버측에 저장하고 관리하는 Session Id를 제공한다
  • Http Session은 Cookie를 사용하여 구현된다
  • Http Sesiion은 사용자 로그인 정보를 관리할 때 사용, 사용자가 다시 접속해도 유지된다
  • Http Session✅서버에서 관리 -> 사용자가 임의로 조작 불가
  • 임의의 랜덤 값(UUID), Htttps에 의해 암호화 된다

인증 과정

  1. 먼저 사용자가 로그인 웹에서, 요쳥정보(id,password)를 통해 로그인을 시도한다
  2. 만약 로그인이 성공하면 -> 서버는 서버에서 관리하는 HttpSession세션id를 만들어 그 값을 저장한다
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public void login(LoginRequest loginRequest, HttpSession httpSession){

        String id = loginRequest.getId();
        String password = loginRequest.getPassword();

        Optional<UserDto> optionalUser = userRepository.findByName(id);

        if (optionalUser.isPresent()){
            UserDto userDto = optionalUser.get();
            if (userDto.getPassword().equals(password)){
                // 세션에 정보 저장 -> 서버에서 관리되는 정보
                httpSession.setAttribute("USER",userDto);
            }else {
                throw new RuntimeException("Password not match");
            }
        } else {
            // 없는 유저
            throw new RuntimeException("User not found");
        }

    }
}
  • USER라는 session id를 만들어서 httpSession에 정보를 저장하였다
  1. 다시 클라이언트가, 서버에 요청을 할 때 발급받은 Session id를 이용해서 웹 인증을 요청한다
@RestController
@RequestMapping("/api/user")
public class UserApiController {
    @GetMapping("/me")
    public UserDto me(HttpSession httpSession){

        UserDto user= (UserDto) httpSession.getAttribute("USER");
        if (user != null){
            return user;
        }else {
            return null;
        }

    }
}
  1. 로그인이 되면, 해당 session에 저장된 값을 사용할 수 있다

로그인에 실패해도, Jsession은 항상 생긴다

  • Jsession : 웹 페이지 연결시 웹 서버에서 임의적으로 세션을 하나만든다. 이때 제공하는 Session id이다, 서블릿에서 발행한 session id이다

  • Http Cookie는 웹 브라우저와 웹 서버간의 상태정보를 유지하기 위한 기술이다
  • 쿠키는 로컬에 저장하고, 필요할 때마다 서버에 전송해 사용자 정보를 유지한다
  • Http 헤더에 Set-Cookie같은 헤더를 이용해 서버에서 클라이언트로 전송된다
  • 쿠키는 클라이언트 측에 저장된다
  • 서버가 상태정보를 확인할려면 -> 쿠키를 클라이언트에게 전송받아야 한다
  • 쿠키는 유효기간을 갖는다
  • 보안 문제...-> Https같은 보안 프로토콜을 이용해야 한다
  • 브라우저에서 관리되므로, 쿠키를 삭제하거나 다른 브라우저에서 접속하는 경우 쿠키를 공유할 수 없다

인증 과정

  1. 사용자가 로그인 페이지에서,요쳥정보(id,password)를 통해 로그인을 시도한다
  2. 서버는 사용자 검증 -> 로그인 성공고유 id와 인증 토큰(쿠키)를 생성
@Service
@RequiredArgsConstructor
public class UserService {

    private final UserRepository userRepository;

    //login logic
    public String login(LoginRequest loginRequest, HttpServletResponse response){

        String id = loginRequest.getId();
        String password = loginRequest.getPassword();

        Optional<UserDto> optionalUser = userRepository.findByName(id);

        if (optionalUser.isPresent()){
            UserDto userDto = optionalUser.get();

            if (userDto.getPassword().equals(password)){

              
                Cookie cookie = new Cookie("authorization-cookie",userDto.getId());
                cookie.setDomain("localhost");  // naver.com, daum.net, dev.xxx.com
                cookie.setPath("/");
                cookie.setHttpOnly(true);   // <-- 자바 스크립트로 조작 불가능
//                cookie.setSecure(true);  // <-- https에서만 사용되도록 설정
                cookie.setMaxAge(-1);  // session과 통일, 시간을 지정해줄 수 있음

                response.addCookie(cookie);
            }

        }else {
            throw new RuntimeException("User not found");
        }
        return null;
    }
}
  • new Cookie를 만들어서, 값을 넣어준다
  1. 서버는 생성된 쿠키를 -> Http 응답 헤더에 담아(setCookie())서 클라이언트에게 전송
  2. 클라이언트는 받은 쿠키를 로컬에 저장한다
  • 이부분은 브라우저에서 자동으로 해준다
  1. 클라이언트는 이후 서버에 요청할 때마다, Http 헤더에 토큰을 담아서 전송
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/user")
public class UserApiController {

    private final UserRepository userRepository;
    @GetMapping("/me")
    public UserDto me(@CookieValue(name = "authorization-cookie",required = false) 
    String authorizationCookie){


        log.info("authorizationCookies : {}",authorizationCookie);
        Optional<UserDto> optionalUserDto = userRepository.findById(authorizationCookie);
        return optionalUserDto.get();
        }
  • @CookieValue 어노테이션을 사용하였다
  1. 서버는 토큰을 확인하여 -> 인증 성공 -> 응답 생성

Http Header

  • Rest 클라이언트를 사용하는 네이티브, 즉 안드로이드 IOS쪽에서 많이 사용하는 방식
  • client쪽에 시큐리한 공간을 가질 수 있다
  • 웹하고는 방식이 조금 다르다
  • 서버와 클라이언트 간의 인증을 Http 헤더를 통해서 수행하는 방식
  • Http Basic, Http Diest, Oauth같은 프로토콜을 통해서 구현
  • 특정 header에 token을 넣어서 사용자를 인식,인증

음.. 쿠키response header에 정보가 담겨서 가지 않았나???

  • 맞다

결국 사용하는 브라우저의 request header에 모든 정보가 담겨져서 나간다

  • 쿠키 같은 경우 자동으로 정보가 담겨서 나가는데, 쿠키는 브라우저 또는 클라이언트, 안드로이드, ios의 특정 영역에 변수로 뽑아서 따로 지정을 해줘야한다
  • 웹 브라우저 같은 경우, 이러한 쿠키 값들을 자동으로 관리(만료시 삭제), 해주므로 쿠키 방식이 웹 브라우저에 잘 어울린다
  • rest 클라이언트를 사용하는 안드로이드, ios쪽에서는 이런 만료같은 것들을 변수로 뽑아 하나하나 고나리해줘야한다
  • 결론적으로 쿠키를 관리하는 것은 웹 브라우저에서 더욱 편하다
  • 어쩌피 쿠키또한 header에 담아서 관리해주는 것이므로, 웹인지 아닌지에 따라 자동으로 관리해주는지의 차이라고 볼 수 있다
  • 결국 http header에 토큰을 담든,뭐든... http 헤더를 통해 인증 정보를 전달해주는 것이다
profile
개발 공부,정리

0개의 댓글