2023.08.31.목.TIL

heeh·2023년 8월 31일

TIL

목록 보기
76/82
post-thumbnail

2023.08.31.목.TIL

  • 할 것
    • 11시 회의 - 기능 합치기

비밀번호 이어서 작업!

  • UnsatisfiedDependencyException 해결하기
  • redis에서 암호화된 비밀번호가 계속 바뀌는 것을 확인!
    • 왜 DB에서 바뀌지 않을까?
      → User가 영속성 컨텍스트가 아닌 밖에 있는 User여서 Transactional로 관리가 되지 않았다
    • User를 넣어주어야 영속성 컨텍스트가 돼서 Transactional가 작동된다
      User targetUser = userRepository.findById(user.getId())
                      .orElseThrow(() -> new IllegalArgumentException("회원이 존재하지 않습니다"));
      • DB에서 직접 꺼내온 객체(User)가 되니까 영속성 컨텍스트가 되고 Update가 이루어진다
  • 비밀번호를 비교할 때 인코딩 되지 않은 비밀번호와 인코딩된 비밀번호 비교
     for (Password passwordHistory : passwordHistoryList) {
                    if (passwordEncoder.matches(password, passwordHistory.getUpdatedPassword())) {
                        throw new IllegalArgumentException("이미 3회 이내 변경되었던 비밀번호입니다.");
                    }
                }
    • (passwordEncoder.matches(password, passwordHistory.getUpdatedPassword()))
      • (passwordEncoder.matches(인코딩 되지 않은 비밀번호, 인코딩된 비밀번호()))
  • passwordHistoryList.forEach(password1 -> System.out.println(password1.getUpdatedPassword()));
    • Password 목록이 찍힘
  • redis는 key-value 값 사용!
    • 멤버 아이디 하나당 password가 하나만 들어감 = 과거에 썼던 password를 기억하는 기능을 쓰지 못한다
      • 3개의 비밀번호를 기억해서 그것들의 사용 제한을 하고 싶은건데, 3개를 저장하지 못한다

      • key-value 데이터를 사용하는 redis는 값을 한 개만 저장하고 새로운 값이 들어오면 이미 저장된 한 개의 값에 덮어 씌워진다 = 여러 값을 저장하지 못함 = 과거 3개의 비밀번호 값을 저장하지 못함

      • DB로 변경!!!!!!!!!!!!!!!!!!!!! 목요일 오전에 후다닥 해보자!

        변경 사항
        DB가 아닌 redis로 저장을 하려고 시도 했습니다.
        redis는 새로운 값이 들어오면 이미 저장된 한 개의 값에 덮어 씌워지고 여러 값을 저장하지 못합니다.
        key-value 데이터를 사용하는 redis는 값을 한 개만 저장해서 최근 3회 사용한 비밀번호를 기억하고 사용에 제한을 두는 기능을 구현할 수 없어서 redis로 작업하는 부분을 DB로 변경하였습니다.
        
        Todo List
        UserServiceUserRepository에서 findTop4ByUserOrderByCreatedAtDesc 쿼리문을 사용하고 있습니다.
        RunTime과 포스트맨에서 작동되는 것을 확인했지만 이후 리팩토칭에서 빌더 패턴 사용, 코드의 간결화 등의 문제로 수정되는 것들에 영향을 받아 변경될 것 같습니다.
        
        Check List
         포스트맨으로 체크해 보았나요?
         테스트 코드를 작성하셨나요?
        트러블 슈팅
        ###UnsatisfiedDependencyException의 해결
        id import 경로 문제
        import jakarta.persistence.Id;import org.springframework.data.annotation.Id;
        
        DB로 변경 전, redish 사용시에 일어났던 이슈입니다. redis를 사용하기 위해 만들었던 entity class에 있는 @id의 경로에 오류가 있었습니다.
        
        이슈 번호 : Reseolves: [feature] 비밀번호 수정 #25
  • reids 예제…
    • reids를 쓰는 password
      @RedisHash(value = "password")
      @Getter
      @AllArgsConstructor
      @NoArgsConstructor
      @Builder
      public class Password {
          @Id
          private Long memberId; // 사용자 식별
      
          private String updatedPassword; // 변경된 비밀번호
      
      }
    • ex) toEntity
      public Password toEntity(User user, String encodedPassword) {
              Password updatePassword = Password.builder()
                      .memberId(user.getId())
                      .updatedPassword(encodedPassword)
                      .build();
              return updatePassword;
    • PasswordRepository
      public interface PasswordRepository extends CrudRepository<Password,Long> {
      
          List<Password> findByMemberId(Long id);
      }
  • DB…바꿔주자…
    • UpdatePasswordRequestDto
      @Builder
      @Getter
      @AllArgsConstructor
      @NoArgsConstructor
      public class UpdatePasswordRequestDto {
          private String updatePassword;
      
          public void updatePassword(String updatePassword) {
              this.updatePassword = updatePassword;
          }
      • UpdatePasswordRequestDto 의 updatePassword를 빌더 패턴으로 해주고 싶은데 ㅠㅠ 빌더 패턴으로 맞춰주면 User user도 받아줘야 한다…
        public UpdatePasswordRequestDto updatePassword(User user, String updatePassword) {
                return UpdatePasswordRequestDto.builder()
                        .id(user.getId())
                        .updatePassword(updatePassword)
                        .build();
      • 그렇다면 Service - public void updatePassword (UpdatePasswordRequestDto requestDto, User user) 에 있는
        requestDto.updatePassword(passwordEncoder.encode(requestDto.getUpdatePassword()));
        requestDto.updatePassword(passwordEncoder.encode(requestDto.getUpdatePassword()), user);
        • 이 로직 안에도 user가 추가 되는데 이미 사용한 3개의 비밀번호 사용 제한이 되지 않는다….
        • 잘못된 방법인 것 같다!

수정 요청

  • 비밀 번호 수정 리팩토링
    • 회원가입할때 회원가입한 비밀번호를 패스워드 매니저에 넣어야 함
    • 빌드 패턴써서 코드정리
    • 현재 비밀번호 입력 받아서 검증한 후에 비밀번호 변경하기
requestDto.updatePassword(passwordEncoder.encode(requestDto.getUpdatePassword()));
  • 회원가입 시 썼던 비밀번호 PasswordManager 엔티티에 저장
    • before (생성자 사용)
      // 회원가입 시 썼던 비밀번호를 PasswordManager 엔티티에 저장
              PasswordManager passwordManager = new PasswordManager(user, password); // originalPassword는 회원가입 시 사용된 비밀번호
          passwordManagerRepository.save(passwordManager);
    • after (빌더 패턴 사용)
      // 회원가입 시 썼던 비밀번호를 PasswordManager 엔티티에 저장
              PasswordManager passwordManager = PasswordManager.builder()
                      .user(user)
                      .password(password)    // 업데이트된 비밀번호
                      .build();
              passwordManagerRepository.save(passwordManager);
  • users 테이블의 user 데이터가 삭제 되지 않는 이유
    • User
      @OneToMany(mappedBy = "user", cascade = CascadeType.REMOVE)
          private final List<PasswordManager> passwordManagerList = new ArrayList<>();
    • @OneToMany를 걸어 줬기 때문에 user 데이터를 먼저 삭제 할 수 없다
    • password_manager에 연관되어 있는 데이터를 먼저 삭제해주면 users 테이블의 user 데이터를 삭제 할 수 있다
  • 최근 3번 사용한 비밀번호는 사용할 수 없게 하기 위해 수정
    • UserService

      @Transactional
          public void updatePassword (UpdatePasswordRequestDto requestDto, User user) {
              // 프로필 수정 시 비밀번호를 한 번 더 입력받는 과정
              if (!passwordEncoder.matches(requestDto.getPassword(), user.getPassword())) {
                  throw new IllegalArgumentException("비밀번호 인증에 실패했습니다.");
              }
      
              // 최근 3번 사용한 비밀번호 조회
              List<PasswordManager> passwordList = passwordManagerRepository.findTop4ByUserOrderByCreatedAtDesc(user);
      
              for (PasswordManager passwordHistory : passwordList) {
                  if (passwordEncoder.matches(requestDto.getUpdatePassword(), passwordHistory.getPassword())) {
                      throw new IllegalArgumentException("최근 3번 사용한 비밀번호는 사용할 수 없습니다.");
                  }
              }
      
              // 받아온 비밀번호 암호화 시켜줌
              requestDto.updatePassword(passwordEncoder.encode(requestDto.getUpdatePassword()));
      
              User targetUser = userRepository.findById(user.getId())
                      .orElseThrow(() -> new IllegalArgumentException("회원이 존재하지 않습니다"));
      
              targetUser.updatePassword(requestDto); // 패스워드 업데이트 메소드 호출
      
              passwordManagerRepository.save(new PasswordManager(user, requestDto.getUpdatePassword()));
      
          }
      • 변경 후
        	@Transactional
            public void updatePassword (UpdatePasswordRequestDto requestDto, User user) {
                User loginedUser = findUser(user.getUsername());
                //입력한 비밀번호와 DB 내 비밀번호가 동일할 시
                if (passwordEncoder.matches(requestDto.getPassword(), loginedUser.getPassword())) {
        
                    //가장 최근 사용한 3개의 비밀번호를 가져오기
                    List<String> usedPasswords = passwordManagerRepository.findPasswordTopThree(loginedUser);
                    System.out.println("로그:"+usedPasswords);
                    for(String usedPassword : usedPasswords){
        
                        //바꾸려는 비밀번호가 패스워드관리테이블 내 최근 3개의 비밀번호 중 하나와 일치하는 경우
                        if(passwordEncoder.matches(requestDto.getUpdatePassword(),usedPassword)){
                            System.out.println("최근 3회 이내 사용된 비밀번호와 같아서 비밀번호를 변경 할 수 없습니다.");
                            throw new IllegalArgumentException("최근 3회 이내 사용된 비밀번호로는 변경 할 수 없습니다.");
                        }
                        System.out.println("최근 3회 이내 사용된 비밀번호와 달라서 비밀번호를 변경 했습니다.");
                    }
        
                    //비밀번호 변경
                    String newPassword = passwordEncoder.encode(requestDto.getUpdatePassword());
                    loginedUser.updatePassword(newPassword);
        
                    //비밀번호 관리테이블에 추가
                    PasswordManager passwordManager = new PasswordManager(newPassword, user);
                    passwordManagerRepository.save(passwordManager);
                }
                else
                    throw new IllegalArgumentException("입력한 현재 비밀번호가 일치하지 않습니다.");
        
            }
        
            //user가 db내 존재하는지 검사
            private User findUser(String username) {
                return userRepository.findByUsername(username).orElseThrow(() ->
                        new IllegalArgumentException("존재하지 않는 사용자 입니다.")
                );
            }
    • UserRepository

      ```java
      public interface PasswordManagerRepository extends JpaRepository <PasswordManager,Long> {
      
          List<PasswordManager> findTop4ByUserOrderByCreatedAtDesc(User user);
      
      }
      ```
      
      - 변경 후
          
          ```java
          public interface PasswordManagerRepository extends JpaRepository <PasswordManager,Long> {
          
              Optional<PasswordManager> findByUser(User user);
          
              //DESC : 내림차순(높은숫자부터 낮은숫자)
              //LIMIT 3 : 3건만 조회
              @Query("SELECT pm.password FROM PasswordManager pm WHERE pm.user = :user ORDER BY pm.id DESC LIMIT 3")
              List<String> findPasswordTopThree(@Param("user") User user);
          
          }
          ```
          
      변경 사항
      password_manager
      회원가입시 입력한 비밀번호를 password_manager에 담아서 저장하고 비밀번호 변경시 기억하여 최근 3회 비밀번호 사용 제한에 포함했습니다.
      빌더 패턴으로 변경
      UpdatePasswordRequestDto에 빌더 패턴을 써주었으나 UserService 내에 public void signUp(SignupRequestDto requestDto)에서 빌더 패턴을 사용하게 했습니다.
      현재 비밀번호 검증 후 비밀번호 변경 가능으로 수정
      UpdatePasswordRequestDto에 현재의 비밀번호(password)와 변경할 비밀번호(updatePassword)를 필드로 선언해주고 UserService 내에 public void updatePassword (UpdatePasswordRequestDto requestDto, User user)if문을 넣어주었습니다.
      Todo List
      Check List
       포스트맨으로 체크해 보았나요?
       테스트 코드를 작성하셨나요?
      트러블 슈팅
      // 회원가입 시 썼던 비밀번호를 PasswordManager 엔티티에 저장
              ``PasswordManager passwordManager = PasswordManager.builder()
                      .user(user)
                      .password(password)    // 업데이트된 비밀번호
                      .build();
              passwordManagerRepository.save(passwordManager);
      DB 데이터 삽입으로 테스트
      위 코드로 인해 회원가입시 입력했던 비밀번호가 password_manager 테이블에 저장에 되어야 하는데 값이 들어오지 않았습니다.
      코드에 문제가 있는 것은 아닌 것 같고... DB에 데이터를 넣어주는 것만으로는 테스트가 이루어질 것 같지 않았습니다.
      
      해결
      UserServicepublic void signUp(SignupRequestDto requestDto)에서 email, sms 인증 관련을 주석처리하고 포스트맨으로 회원가입을 진행해서 회원가입시 입력했던 비밀번호가 password_manager 테이블에 저장되는 것을 확인했습니다.
      
      또한 최근 3번 사용한 비밀번호 조회를 위해 이전에 작성했던 findTop4ByUserOrderByCreatedAtDesc 관련 로직을 UserServicePasswordManagerRepository에서 수정해줬습니다. (참고:https://github.com/lazygyu97/SNS)
      
      이슈 번호 : Reseolves: [feature] 비밀번호 수정 #25

회의 등 기능 해야 할 것!

해야 할 것 들 …

1. CI/CD
    1. CI : ㅇㅇ님의 테스트 코드를 활용해 ci 흐름을 배워보고 적용 
    2. CD : 백엔드 서버를 배포하여 CD 구현시작

2. 게시글 관련
    1. 이미지 업로드 : 게시글 작성, 수정에 대해 이미지 추가 (최대 3장까지 …)
    2. 게시글 검색 : 페이징 처리 기반으로  제목, 제목+내용, 내용에 대해 키워드를 통해 검색하기
    3. 게시글 추천 : 좋아요 , 지역별로 사용자에게 추천해주는 메서드 (Entity 자체에 지역 칼럼 추가 고려해야함
    4. 현재 게시글 조회 시 좋아요와 댓글이 같이 넘어오지 않기 때문에 양방향 설정 해줘야함

3. 서울시 api
    1. .각 카테고리 조회 구현 및 페이징 처리 적용
    2. 스케줄링에서 RestTemplateConfig를 추가하여 사용하고 있는데 수행하고 있는 작업을 OpenApiService에서 처리하는 방법 생각해보기  -> 강제 업데이를 위해 서비스 단에서 처리해야 좋을 것 같다.
    3. 가져온 서비스 정보를 스크랩,댓글,좋아요 하는 방식에 대해 고민해보기 (주기적으로 업데이트 되면서 id값이 바뀌는 문제)
    4. 사용자 별 추천 서비스 범위 설정하여 로직 구현

4. 소셜로그인 : 카카오,네이버, 구글 oauth2를 활용한 소셜 로그인 구현
5. 문서 최신화: SA 각 분류 별 변경점에 대한 문서 최신화 , 깃허브 리드 미 작성 
6. 알림 기능 : 사용자의 글에 댓글이 달리거나 좋아요가 눌렸을 때 알림 
7. 채팅 기능 : 팔로우한 사용자끼리 채팅하는 기능 구현
1. CI/CD
1-1. CI : ㅇㅇ님의 테스트 코드를 활용해 ci 흐름을 배워보고 적용
1-2. CD : 백엔드 서버를 배포하여 CD 구현시작

2. 게시글 관련
2-1. 이미지 업로드 : 게시글 작성, 수정에 대해 이미지 추가 (최대 3장까지 ...)
2-2. 게시글 검색 : 페이징 처리 기반으로 제목, 제목+내용, 내용에 대해 키워드를 통해 검색하기
2-3. 게시글 추천 : 좋아요 , 지역별로 사용자에게 추천해주는 메서드 (Entity 자체에 지역 칼럼 추가 고려해야함
2-4. 현재 게시글 조회 시 좋아요와 댓글이 같이 넘어오지 않기 때문에 양방향 설정 해줘야함

3. 서울시 api
3-1. .각 카테고리 조회 구현 및 페이징 처리 적용
3-2. 스케줄링에서 RestTemplateConfig를 추가하여 사용하고 있는데 수행하고 있는 작업을 OpenApiService에서 처리하는 방법 생각해보기 -> 강제 업데이를 위해 서비스 단에서 처리해야 좋을 것 같다.
3-3. 가져온 서비스 정보를 스크랩,댓글,좋아요 하는 방식에 대해 고민해보기 (주기적으로 업데이트 되면서 id값이 바뀌는 문제)
3-4. 사용자 별 추천 서비스 범위 설정하여 로직 구현

4. 소셜로그인 : 카카오,네이버, 구글 oauth2를 활용한 소셜 로그인 구현
4-5. 문서 최신화: SA 각 분류 별 변경점에 대한 문서 최신화 , 깃허브 리드 미 작성
4-6. 알림 기능 : 사용자의 글에 댓글이 달리거나 좋아요가 눌렸을 때 알림
4-7. 채팅 기능 : 팔로우한 사용자끼리 채팅하는 기능 구현

8. 비밀 번호 수정 리팩토링
8-1. 회원가입할때 회원가입한 비밀번호를 패스워드 매니저에 넣어야함
8-2. 빌드 패턴써서 코드정리
8-3. 현재 비밀번호 입력 받아서 검증한 후에 비밀번호 변경하기
  • 8번 모두 완료
    → 팀장님 : 레디스로 비밀번호, 최근 3회 사용한 비밀번호 제한를 구현할 수 있다?!
    - redis 관계형 데이터베이스가 아님(noSQL) → 한 컬럼 안에 List 담을 수 있다
    → 이 기능을 쓰는 근거
  • ApiResponseDto의 Controller 반환 메세지를 통일하자!
    • ~습니다, ~성공 같은 Msg
    • 성공 시에 Response를 반환해주고 있지만, 실패 시에는 해주고 있지 않아서 이 부분도 확인!
  • API 수정
  • 알람 기능
    • 페어프로그래밍…. 많이 어렵다고 함..?
    • 부리더님 - 소켓
    • 나 - 레디스
    • 소켓, 레디스 같이 진행되어야 하기 때문에 관련하여 공부!!!

기술 문제 14

💡 ORM을 사용하면서 쿼리가 복잡해지는 경우에는 어떻게 해결 하는게 좋을까요?

ORM

ORM은 "Object-Relational Mapping"의 약어로, 객체와 관계형 데이터베이스 간의 데이터를 변환하고 상호 작용하기 위한 기술입니다. 관계형 데이터베이스는 테이블과 열의 형태로 데이터를 저장하고 관리하는 반면, 객체 지향 프로그래밍에서는 클래스와 객체의 형태로 데이터를 다룹니다. ORM은 이러한 두 가지 모델 간의 간극을 줄이기 위해 사용되며, 개발자들이 객체 지향 프로그래밍 언어를 사용하여 데이터베이스와 상호 작용할 수 있도록 도와줍니다.

ORM의 주요 목표는 다음과 같습니다:

  1. 객체와 데이터베이스 간의 매핑: ORM은 객체를 데이터베이스 테이블로, 객체의 속성을 테이블의 열로 매핑시킵니다. 이를 통해 객체를 데이터베이스에 저장하고 검색하는 등의 작업을 객체 지향적인 방식으로 처리할 수 있습니다.
  2. 쿼리 생성 및 실행: ORM은 개발자가 SQL을 직접 작성하지 않아도 되도록 도와줍니다. ORM을 사용하면 쿼리를 생성하고 실행하는 과정을 추상화하여 개발자가 좀 더 간편하게 데이터베이스와 상호 작용할 수 있습니다.
  3. 데이터베이스 추상화: ORM을 사용하면 특정 데이터베이스 시스템에 종속되지 않고 여러 종류의 데이터베이스를 사용할 수 있습니다. ORM은 백엔드 데이터베이스 시스템의 차이점을 추상화하여 개발자가 일관된 코드를 유지할 수 있도록 도와줍니다.
  4. 관계 관리: ORM은 객체 간의 관계를 데이터베이스 내에 효과적으로 매핑하고 관리할 수 있도록 지원합니다. 예를 들어, 객체 간의 일대다, 다대다 관계를 데이터베이스의 외래 키와 조인을 통해 처리합니다.
  5. 자동화된 작업: ORM은 데이터베이스 연산에 필요한 반복적인 작업들을 자동화합니다. 데이터의 삽입, 갱신, 삭제, 쿼리 등의 작업을 더 쉽게 처리할 수 있습니다.

주요한 ORM 프레임워크에는 Hibernate (Java), Entity Framework (.NET), Django ORM (Python), Sequelize (Node.js), SQLAlchemy (Python) 등이 있습니다. 이러한 프레임워크들은 개발자들이 데이터베이스와의 상호 작용을 추상화하고 편리하게 처리할 수 있도록 도와줍니다.

ORM 사용시 쿼리가 복잡해지는 경우 해결

  1. Raw SQL Query 사용: ORM은 편리하지만 모든 쿼리를 ORM을 통해 작성하지 않아도 됩니다. 복잡한 쿼리의 경우에는 직접 Raw SQL Query를 작성하여 실행할 수 있습니다. 이렇게 하면 ORM의 제약을 더욱 느끼지 않고 필요한 쿼리를 실행할 수 있습니다.
  2. Stored Procedure 활용: 데이터베이스에 저장 프로시저(Stored Procedure)를 작성하여 복잡한 로직을 데이터베이스 내부에서 처리하도록 할 수 있습니다. ORM을 사용하여 저장 프로시저를 호출할 수 있습니다.
  3. 최적화된 ORM 쿼리 사용: 대부분의 ORM은 복잡한 쿼리를 작성할 수 있는 다양한 기능을 제공합니다. ORM 문서를 확인하여 조인, 집계 함수, 서브쿼리 등을 최적화된 방식으로 작성하는 방법을 익히는 것이 좋습니다.
  4. 인덱스 및 성능 최적화: 쿼리 성능을 향상시키기 위해 데이터베이스에 적절한 인덱스를 생성하고, 필요한 경우 데이터베이스 튜닝을 수행합니다. ORM을 사용하더라도 데이터베이스 엔진의 성능을 최대한 활용하는 것이 중요합니다.
  5. 쿼리 분할: 하나의 복잡한 쿼리 대신 여러 개의 간단한 쿼리로 나누어서 실행하는 방식을 고려할 수 있습니다. 이렇게 하면 데이터를 중간 단계에서 얻어와서 애플리케이션 레벨에서 조합하거나 처리할 수 있습니다.
  6. 캐싱 활용: 자주 반복되는 복잡한 쿼리의 결과를 캐싱하여 성능을 향상시킬 수 있습니다. 캐싱을 통해 데이터베이스 부하를 줄이고 쿼리 실행 속도를 개선할 수 있습니다.
  7. ORM 확장: 몇몇 ORM은 확장성을 위해 커스텀 쿼리나 표현식을 작성할 수 있는 기능을 제공합니다. 이를 활용하여 ORM 자체의 기능을 확장할 수 있습니다.
  8. 문제 영역 분리: 복잡한 쿼리가 많이 필요한 부분을 별도의 모듈로 분리하여 관리하고, 해당 모듈 내에서 쿼리를 직접 작성하거나 관리할 수 있습니다.
  9. 튜닝 및 최적화 도구 사용: ORM에서 발생하는 성능 문제를 파악하고 해결하는 데 도움을 주는 다양한 도구와 모니터링 시스템을 활용할 수 있습니다.

  • 직접 SQL 문(Raw SQL 쿼리)을 사용하거나 데이터베이스 내부의 저장 프로시저를 활용하여 복잡한 로직의 문제를 처리하도록 합니다. 또한 사용하는 쿼리의 결과를 잠시 저장해두는 '캐싱'을 고려해보고, 데이터 정리를 통해 빠르게 찾을 수 있게 도와줄 '인덱스'를 만들어서 전체적인 성능을 개선합니다.
  • 피드백

기술 문제 15

💡 GET, POST의 개념과 함께 데이터 흐름에 대해서 설명해주세요.

HTTP

HTTP는 웹에서 데이터를 주고받는 데 사용되는 프로토콜입니다. 그 중에서도 가장 널리 사용되는 메서드는 GET과 POST입니다. 이들 메서드는 데이터를 서버로 보내거나 서버에서 받는 데 사용됩니다.

GET

GET 메서드:

  • 개념: GET은 서버로부터 정보를 요청할 때 사용되는 메서드입니다. 주로 브라우저의 주소창에 URL을 입력하여 페이지를 요청할 때 사용됩니다.
  • 데이터 전달: GET 메서드는 데이터를 URL의 쿼리 파라미터 형태로 전달합니다. 즉, URL 뒤에 ?key=value와 같이 데이터를 붙여서 전달합니다.
  • 데이터 노출: GET은 URL에 데이터가 노출되기 때문에 보안에 취약할 수 있습니다. 또한 데이터의 크기에 제한이 있습니다.
  • 용도: 데이터 조회나 페이지 이동 등에서 주로 사용됩니다.

GET:

  • 사용자가 브라우저의 주소창에 https://example.com/profile?user_id=123을 입력합니다.
  • 브라우저가 서버에 GET 요청을 보냅니다.
  • 서버는 user_id가 123인 사용자의 프로필 정보를 데이터베이스에서 조회합니다.
  • 서버는 조회한 정보를 HTML 형태로 응답합니다.
  • 브라우저는 응답 받은 HTML을 렌더링하여 사용자에게 보여줍니다.

POST

POST 메서드:

  • 개념: POST는 서버에 데이터를 제출할 때 사용되는 메서드입니다. 주로 사용자가 폼을 작성하고 제출하는 경우에 사용됩니다.
  • 데이터 전달: POST 메서드는 HTTP 요청의 본문(body)에 데이터를 담아서 서버로 보냅니다.
  • 데이터 보안: POST는 URL에 데이터가 노출되지 않기 때문에 GET보다는 보안이 더 좋습니다.
  • 용도: 데이터의 생성, 수정, 삭제와 같은 변경 작업을 처리할 때 주로 사용됩니다.

POST:

  • 사용자가 웹 페이지에서 로그인 폼을 작성하고 "로그인" 버튼을 클릭합니다.
  • 브라우저는 로그인 정보를 POST 요청의 본문에 담아서 서버에 보냅니다.
  • 서버는 전달받은 로그인 정보를 확인하여 인증 여부를 판단합니다.
  • 서버는 인증이 성공했다면 사용자의 개인 페이지로 리다이렉트하는 응답을 보냅니다.
  • 브라우저는 응답을 받고 리다이렉트된 페이지를 표시합니다.

  • GET과 POST는 HTTP 메서드로, GET은 URL를 통해 정보를 요청할 때 사용하고, POST는 서버에 데이터를 보낼 때 사용합니다. GET은 주로 조회나 페이지 이동에 사용되며 URL에 데이터를 붙여 전송하기 때문에 URL에 데이터가 노출될 수 있습니다. POST는 데이터 생성, 수정, 삭제에 사용되며 POST는 요청 본문(JSON)에 데이터를 넣어 서버로 데이터가 전달되기 때문에 데이터의 노출이 없어서 보안이 우수합니다.
  • 피드백
profile
공부하자개발하자으쌰으쌰

0개의 댓글