[241113 TIL] AI 검증 비즈니스 프로젝트

카테고리, 가게, 리뷰 CRUD API 구현

 

  • API 동작 확인
  • 리뷰 평점 스케줄러 적용
  • Soft Delete 적용

API 동작 확인

⚠️ 트러블슈팅 ⚠️

 

1. 문제 정의

  • 가게 생성 API 동작 확인 중 에러 발생 (POST)
org.springframework.dao.DataIntegrityViolationException: could not execute statement [Duplicate entry 'b\xDD\x98\xF0\xBD\x8E\x11\xED\x93\xAB2P\x96\xB3\x9FG' for key 'p_stores.UK260ia2wautdp3fq67hyklg3cu'] [/* insert for com.sparta.gourmate.domain.store.entity.Store */insert into p_stores (average_rating,category_id,created_at,created_by,deleted_at,deleted_by,is_deleted,location,name,updated_at,updated_by,user_id,id) values (?,?,?,?,?,?,?,?,?,?,?,?,?)]; SQL [/* insert for com.sparta.gourmate.domain.store.entity.Store */insert into p_stores (average_rating,category_id,created_at,created_by,deleted_at,deleted_by,is_deleted,location,name,updated_at,updated_by,user_id,id) values (?,?,?,?,?,?,?,?,?,?,?,?,?)]; constraint [p_stores.UK260ia2wautdp3fq67hyklg3cu]

 

 

  • org.springframework.dao.DataIntegrityViolationException
    • 데이터베이스에서 중복된 값이 삽입되려고 했을 때 발생하는 오류

2. 원인 추론

 

1) 가게 엔티티에 중복된 값을 허용하지 않는 컬럼 확인

  • id - UUID 로 자동 생성되므로 고려 대상 아님
  • user_id - 같은 유저로 여러 개의 가게 생성이 가능됨을 확인
  • category_id - 같은 카테고리의 가게를 생성하려고 할 때 위의 에러 발생

2) 카테고리 엔티티와 가게 엔티티의 연관관계 확인

  • 현재 카테고리와 가게의 연관관계 - @OneToOne
  • 한 가게 당 하나의 카테고리를 갖기에 위 연관관계 설정

3) 연관관계 고려

  • @OneToOne
    • 한 가게가 하나의 카테고리만 가질 수 있다는 것 의미
    • 예를 들어, "피자 가게" 하나가 "피자 카테고리"를 가진다면 적합
    • 여러 가게가 동일한 카테고리를 공유할 수 있다면, @OneToOne 설정은 적합하지 않음

 

 

3. 해결 방안 및 결과

  • 연관관계 변경
    • 여러 개의 가게가 하나의 카테고리를 공유 ➡️ @ManyToOne 이 적합
    • 가게 엔티티에서 @ManyToOne 사용하고, 카테고리 엔티티에서 @OneToMany 사용
@Entity
public class Store {
	// 중략
    @ManyToOne
    @JoinColumn(name = "category_id")
    private Category category;
   
}



@Entity
public class Category {
	// 중략
    @OneToMany(mappedBy = "category")
    private List<Store> storeList;
    
}
  • 연관관계 변경 후 같은 카테고리를 가진 가게 생성 성공!



[241112 TIL] AI 검증 비즈니스 프로젝트

CRUD 구현


Spring Data Jpa

Containing

  • 컬럼에 특정 문자열이 포함된 엔티티 검색
  • SQL Qurey 의 LIKE 와 같음
// SELECT * FROM Store WHERE category_id = categoryID AND name LIKE %query%;
Page<Store> storeList = storeRepository.findByCategoryIdAndNameContaining(categoryId, query, pageable);

 


 

POSTMAN 

⚠️ 트러블슈팅 ⚠️

 

1. 문제 정의

  • API 테스트 진행을 위해 POSTMAN 을 사용하여 회원가입 진행 중 에러 발생
{
    "code": null,
    "message": "Required request body is missing: public com.sparta.gourmate.domain.user.dto.UserResponseDto com.sparta.gourmate.domain.user.controller.UserController.createUser(com.sparta.gourmate.domain.user.dto.SignupRequestDto)"
}

 

 

2. 원인 추론

  • POSTMAN POST 상황

 

1) 입력 조건을 만족하지 못했나?

@NotBlank
@Size(min = 4, max = 10)
@Pattern(regexp = "^[a-z0-9]+$")
private String username;

@NotBlank
@Size(min = 8, max = 15)
@Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[!@#$%^&*)(+=._-])[a-zA-Z\\d!@#$%^&*)(+=._-]+$")
private String password;

@Email
@NotBlank
private String email;

 

  • 모든 조건 만족

 

2) NOTNULL 값만 작성하고 나머지는 작성하지 않아서 그런가?

  • 회원가입(SignupRequestDto)에 필요한 모든 값을 작성해도 같은 에러 발생

 

3) @RequestBody 가 제대로 작동되고 있는지?

  • 모든 값을 Query Params 으로 넘기고 있음을 확인

 

3. 해결 방안 및 결과

  • Boby - JSON raw 로 값 넘겨주기
{
    "username" : "customer",
    "password" : "customer1!",
    "email" : "customer@naver.com",
    "isAdmin" : false,
    "isOwner" : false

}

 

  • 성공적으로 POST
{
    "id": 3,
    "username": "customer",
    "email": "customer@naver.com",
    "role": "CUSTOMER"
}

 

 

 

사실 너무 어이없는 실수라 트러블슈팅으로 적어도 되나~ 싶지만~

그래도 나는 바보라서 똑같은 실수를 하게 될 수도 있으니 일단 적어놓자...

 


POSTMAN 

로그인 후 토큰 처리

 

Login - POST username, password Authorization

Response Header >  Authorization 값 복사

 

Request Header 에 Authorization 입력


[241111 TIL] AI 검증 비즈니스 프로젝트

[Github] IntelliJ 에서 Git Branch 생성하고 Merge 하기


branch 생성

  1. develop 에서 Update Project
  2. develop 에서 New Branch from 'origin/devlop' 클릭 후 branch 생성
  3. 생성한 branch 로 Checkout

branch 작업 후 Merge

  1. develop 에서 Update Project
  2. 작업하던 branch 로 Checkout
  3. Git > Merge 클릭

 




 

프로젝트명

  • Gourmate

프로젝트 인원

  • 이소현, 김지수, 연제민, 이서영

 

1. API 명세서

도메인 기능 Method URL 권한 request response 추가 설명
유저 회원가입 POST /users/signup ALL {
”username”: “이름”,
”email”: “이메일”,
”password”: “비밀번호”,
”role”: “owner”
}
{
”userId”: 1,
”username”: “이름”,
”email”: “이메일”
”role”: “owner”
}
 
유저 로그인 POST /users/login ALL {
”username”: “이름”,
”password”: “비밀번호”
}
{
”accessToken”: “액세스 토큰”,
”refreshToken”: “리프레시 토큰”
}
 
유저 회원조회 GET /users/{userId} ALL - {
”userId”: 1,
”username”: “이름”,
”email”: “이메일”
”role”: “owner”
}
 
유저 회원목록조회 GET /users?username=name&sortBy=createdAt&isAsc=true&page=1&size=10 MANAGER - [
  {
  ”userId”: 1,
  ”username”: “이름”,
  ”email”: “이메일”
  ”role”: “owner”
  },
  
]
 
유저 회원정보수정 PUT /users/{userId} ALL {
”username”: “이름”,
”email”: “이메일”,
”password”: “비밀번호”
”role”: “owner”
}
{
”userId”: 1,
”username”: “이름”,
”email”: “이메일”
”role”: “owner”
}
 
유저 회원탈퇴 DELETE /users/{userId} ALL - -  
유저 주소등록 POST /users/{userId}/addresses CUSTOMER {
”address”: “배송지”
}
{
”addressId” 1,
”address”: “배송지”
}
 
유저 주소조회 GET /users/{userId}/addresses CUSTOMER - {
”addressId” 1,
”address”: “배송지”
}
 
유저 주소수정 PUT /users/{userId}/addresses/{addressId} CUSTOMER {
”address”: “배송지”
}
{
”addressId” 1,
”address”: “배송지”
}
 
유저 주소삭제 DELETE /users/{userId}/addresses/{addressId} CUSTOMER - -  
               
주문 주문등록 POST /orders CUSTOMER {
”address”: “배송지”,
”request”: “요청사항”,
”storeId”: 1,
”type”: “현장주문”,
”items”: [
    {
        “menuId: 1,
        “quantity: 2,
        “price”: 100
    },
    
]
{
”orderId”: 1,
”paymentId: 1,
”totalPrice”: 10000,
”address”: “배송지”,
”request”: “요청사항”,
”storeId”: 1,
”type”: “현장주문”,
”items”: [
    {
        “menuId: 1,
        “quantity: 2
        “price”: 100
    },
    
]
결제 요청 결과에 따른 상태값
- 결제 실패
- 결제 완료
주문 주문상세조회 GET /orders/{orderId} ALL - {
”orderId”: 1,
”orderStatus”: “배달완료”,
”paymentId: 1,
”totalPrice”: 10000,
”address”: “배송지”,
”request”: “요청사항”,
”storeId”: 1,
”type”: “현장주문”,
”items”: [
    {
        “menuId: 1,
        “quantity: 2
        “price”: 100
    },
    
]
[질문] 목록에서 가져온걸사용해도 될것 같은데 어떤가요?
주문 주문목록조회 GET /orders?query=query&sortBy=createdAt&isAsc=true&page=1&size=10 ALL - “orderList”: [
  {
  ”orderId”: 1,
  ”orderStatus”: “배달완료”,
  ”paymentId: 1,
  ”total_price”: 10000,
  ”address”: “배송지”,
  ”request”: “요청사항”,
  ”storeId”: 1,
  ”type”: “현장주문”,
  ”items”: [
      {
          “menuId: 1,
          “quantity: 2
          “price”: 100
      },
      
  ],
  …,
],
"pageable": {…}
query: 메뉴이름, 가게이름
주문 주문취소 PUT /orders/{orderId} ALL - - 환불 요청 결과에 따른 상태값
- 환불 실패
- 환불 완료


가게에서 수락에 따른 상태값
- 주문 취소대기
- 주문 취소완료
주문 주문내역삭제 DELETE /orders/{orderId} CUSTOMER, MANAGER - -  
주문 결제요청 POST /orders/{orderId}/payments CUSTOMER, MANAGER - {
”pg_info”: “~”,
”price”: 11111
}
PG사 결제연동
주문 환불요청 PUT /orders/{orderId}/payments CUSTOMER, MANAGER - - PG사 결제연동
               
가게 가게등록 POST /stores MANAGER {
"categoryId" : 1,
"storeName" : "storeName”,
"location" : "location”
}
{
”storeId” : 1,
"userId" : 1,
"categoryId" : 1,
"storeName" : "storeName”,
"location" : "location”,
”averageRating” : null
}
 
가게 가게조회 GET /stores/{storeId} ALL - {
”storeId” : 1,
"userId" : 1,
"categoryId" : 1,
"storeName" : "storeName”,
"location" : "location”,
”averageRating” : 4.8
}
 
가게 가게목록조회 GET /stores?query=query&categoryId=1&sortBy=createdAt&isAsc=true&page=1&size=10 ALL - "storeList": [
        {
            "storeId" : 1,
            "categoryId" : 1,  
            "name" : 1         
        },
        {
            "storeId" : 1,
            "categoryId" : 1,  
            "name" : 1         
        },
        
    ],
            "pageable": {
            
            },
          }
query: 메뉴이름, 가게이름
가게 가게정보수정 PUT /stores/{storeId} MANAGER {
"categoryId" : 1,
"storeName" : "storeName",
"location" : "location”
}
{
"storeId" : 1,
"categoryId" : 1,
"storeName" : "storeName”,
"location" : "location”
}
 
가게 가게삭제 DELETE /stores/{storeId} MANAGER - -  
가게 리뷰조회 GET /stores/{storeId}/reviews?sortBy=createdAt&isAsc=true&page=1&size=10 ALL - "reviewList": [
        {
           "storeId” : 1,
           "reviewId” : 1,
           "rating" : 4,
           "content" : "content”
        },
        {
           "storeId” : 1,
           "reviewId” : 2,
           "rating" : 4,
           "content" : "content”   
        },
        
    ],
            "pageable": {
            
            },
          }
 
               
상품 상품등록 POST /menu OWNER {
"storeId” : 1,
"menuName" : "menuName",
"description" : "description”,
"price" : 15000,
”isExcluded” : false
}
{
"storeId” : 1,
"menuId” : 1,
"menuName" : "menuName",
"description" : "description”,
"price" : 15000,
”isExcluded” : false
}
 
상품 상품상세조회 GET /menu/{menuId} ALL - {
"menuId” : 1,
"menuName" : "menuName",
"description" : "description”,
"price" : 15000,
”isExcluded” : false
}
 
상품 상품목록조회 GET /menu ALL - "menuList": [
        {
           "menuId” : 1,
           "menuName" : "menuName",
           "price" : 15000
        },
        {
           "menuId” : 1,
           "menuName" : "menuName",
           "price" : 15000 
        },
        
    ]
 
상품 상품정보수정 PUT /menu/{menuId} OWNER {
"storeId” : 1,
"menuName" : "menuName",
"description" : "description”,
"price" : 15000,
"isExcluded" : true
}
{
"storeId” : 1,
"menuId” : 1,
"menuName" : "menuName",
"description" : "description”,
"price" : 15000,
"isExcluded" : true
}
 
상품 상품삭제 DELETE /menu/{menuId} OWNER - -  
               
리뷰 리뷰등록 POST /reviews CUSTOMER {
"ordeId” : 1,
"storeId” : 1,
"rating" : 4,
"content" : "content”
}
{
"ordeId" : 1,
"storeId" : 1,
"reviewId" : 1,
"rating" : 4,
"content" : "content”
}
 
리뷰 리뷰조회 GET /reviews/{reviewId} ALL - {
"ordeId" : 1,
"storeId" : 1,
"reviewId" : 1,
"rating" : 4,
"content" : "content”
}
 
리뷰 리뷰목록조회 GET /reviews CUSTOMER - “reviewList”: [
  {
  "ordeId" : 1,
  "storeId" : 1,
  "reviewId" : 1,
  "rating" : 4,
  "content" : "content”
  },
  
]
 
리뷰 리뷰수정 PUT /reviews/{reviewId} CUSTOMER {
"ordeId” : 1,
"storeId” : 1,
"rating" : 4,
"content" : "content”
}
{
"ordeId" : 1,
"storeId" : 1,
"reviewId" : 1,
"rating" : 4,
"content" : "content”
}
 
리뷰 리뷰삭제 DELETE /reviews/{reviewId} CUSTOMER - -  
               
카테고리 카테고리생성 POST /categories MANAGER {
"categoryName" : "한식”
}
{
"categoryId" : 1,
"categoryName" : "한식”
}
 
카테고리 카테고리목록조회 GET /categories ALL - "categoryList": [
        {
           "categoryId" : 1,
           "categoryName" : "한식"
        },
        {
           "categoryId" : 2,
           "categoryName" : "중식"
        },
        
    ]
 
카테고리 카테고리수정 PUT /categories/{categoryId} MANAGER {
"content" : "치킨"
}
{
"categoryId" : 2,
"categoryName" : "치킨"
}
 
카테고리 카테고리삭제 DELETE /categories/{categoryId} MANAGER - -  
               
AI_API ai 요청 POST /ai-api MANAGER, OWNER {
"text" : "~~50자 이내로 추천해줘"
}
{
"text" : ""
}
 

2. 테이블 명세서

1. 사용자 테이블(p_users)

필드 이름 데이터 타입 NULL 설명
user_id bigint NOT NULL 사용자 ID, PK
username VARCHAR NOT NULL 사용자 이름
password VARCHAR NOT NULL 비밀번호
email VARCHAR NOT NULL 이메일
role VARCHAR NOT NULL 사용자 역할 (CUSTOMER, OWNER, MANAGER, MASTER)
created_at TIMESTAMP   생성 시간
created_by bigint   생성자 
updated_at TIMESTAMP   수정 시간
updated_by bigint   수정자
deleted_at TIMESTAMP   삭제 시간
deleted_by bigint   삭제자 

 

2. 가게 테이블(p_stores)

필드 이름 데이터 타입 NULL 설명
store_id UUID NOT NULL 가게 ID, PK
user_id bigint NOT NULL 사용자 ID, FK
category_id UUID NOT NULL 카테고리 ID, FK
store_name VARCHAR NOT NULL 가게 이름
location VARCHAR   지역
average_rating DECIMAL   평점
created_at TIMESTAMP   생성 시간
created_by bigint   생성자
updated_at TIMESTAMP   수정 시간
updated_by bigint   수정자 
deleted_at TIMESTAMP   삭제 시간
deleted_by bigint   삭제자

 

3. 주소 테이블(p_addresses)

필드 이름 데이터 타입 NULL 설명
address_id UUID NOT NULL 주소 ID, PK
user_id bigint NOT NULL 사용자 ID, FK
address VARCHAR NOT NULL 주소
address_request VARCHAR   요청사항
created_at TIMESTAMP   생성 시간
created_by bigint   생성자 
updated_at TIMESTAMP   수정 시간
updated_by bigint   수정자 
deleted_at TIMESTAMP   삭제 시간
deleted_by bigint   삭제자

 

4. 리뷰 테이블(p_reviews)

필드 이름 데이터 타입 NULL 설명
review_id UUID NOT NULL 리뷰 ID, PK
user_id bigint NOT NULL 사용자 ID, FK
order_id UUID NOT NULL 주문 ID, FK
store_id UUID NOT NULL 가게 ID, FK
rating INT NOT NULL 별점
review_content TEXT   리뷰 내용
created_at TIMESTAMP   생성 시간
created_by bigint   생성자 
updated_at TIMESTAMP   수정 시간
updated_by bigint   수정자
deleted_at TIMESTAMP   삭제 시간
deleted_by bigint   삭제자

 

5. 카테고리 테이블(p_categories)

필드 이름 데이터 타입 NULL 설명
category_id UUID NOT NULL 카테고리 ID, PK
category_name VARCHAR(100) NOT NULL 카테고리 이름
created_at TIMESTAMP   생성 시간
created_by bigint   생성자
updated_at TIMESTAMP   수정 시간
updated_by bigint   수정자 
deleted_at TIMESTAMP   삭제 시간
deleted_by bigint   삭제자 

 

6. 메뉴 테이블(p_menu)

필드 이름 데이터 타입 NULL 여부 설명
menu_id UUID NOT NULL 메뉴 id, PK
store_id UUID NOT NULL 가게 id, FK
menu_name VARCHAR(20) NOT NULL 메뉴 이름
description VARCHAR(255)   메뉴 설명
price int NOT NULL 메뉴 가격
is_excluded BOOLEAN NOT NULL 메뉴 숨김 여부, false
created_at TIMESTAMP   생성 시간
created_by bigint   생성 아이디
updated_at TIMESTAMP   수정 시간
updated_by bigint   수정 아이디
deleted_at TIMESTAMP   삭제 시간
deleted_by bigint   삭제 아이디

 

7. 주문 테이블(p_orders)

필드 이름 데이터 타입 NULL 설명
order_id UUID NOT NULL 주문 id, PK
user_id bigint NOT NULL 사용자 id, FK
store_id UUID NOT NULL 가게 id, FK
address VARCHAR(255) NOT NULL 배송지
order_request VARCHAR(255) NOT NULL 요청 사항
order_type VARCHAR(20) NOT NULL 주문 유형 (ONLINE, OFFLINE)
order_status VARCHAR(20) NOT NULL 주문 상태 (PENDING, CONFIRMED, CANCELLED)
total_price int NOT NULL  가격
created_at TIMESTAMP   생성일
created_by bigint   생성 아이디
updated_at TIMESTAMP   수정일
updated_by bigint   수정 아이디
deleted_at TIMESTAMP   삭제일
deleted_by bigint   삭제 아이디

 

8. 주문항목 테이블(p_order_items)

필드 이름 데이터 타입 NULL 설명
order_item_id UUID NOT NULL 주문 항목 id, PK
order_id UUID NOT NULL 주문 id, FK
menu_id UUID NOT NULL 메뉴 id, FK
quantity int NOT NULL 주문 수량
created_at TIMESTAMP   생성일
created_by bigint   생성 아이디
updated_at TIMESTAMP   수정일
updated_by bigint   수정 아이디
deleted_at TIMESTAMP   삭제일
deleted_by bigint   삭제 아이디

 

9. 결제 테이블(p_payments)

필드 이름 데이터 타입 NULL 설명
payment_id UUID NOT NULL 결제 id, PK
order_id UUID NOT NULL 주문 id, FK
amount int NOT NULL 결제 금액
payment_status VARCHAR(20) NOT NULL 결제 상태 (SUCCESS, FAIL)
pg_info VARCHAR(20) NOT NULL PG사 결제내역
created_at TIMESTAMP   생성일
created_by bigint   생성 아이디

 

10. AI 테이블(p_ai_api)

필드 이름 데이터 타입 NULL 설명
ai_api_id UUID NOT NULL api 요청 id, PK
user_id bigint NOT NULL 사용자 id, FK
response VARCHAR(255) NOT NULL 대답
created_at TIMESTAMP   생성일
created_by bigint   생성 아이디

 

3. ERD 명세서

4. 인프라 설계서

 

[241104 TIL] 

AI 검증 비즈니스 프로젝트

S.A (Starting Assignments) 작성

  • API 명세서
  • 테이블 명세서
  • ERD 명세서
  • 인프라 설계서

 

테이블 명세서 - (메뉴, 주문, 주문 항목, 결제, AI)

  • 기본값, PK, FK 항목을 따로 만드는 게 나을지?
  • 데이터 감사 로그: 모든 정보에 생성일, 생성 아이디, 수정일, 수정 아이디, 삭제일, 삭제 아이디를 포함
    • 생성자(username) → 생성 아이디(user_id) 로 변경
  • 결제 테이블(p_payments) - amount(결제 금액)
    • 주문 테이블(p_orders) - total_amount(총 가격) 랑 같은거?
    • 할인, 쿠폰 등 적용한다고 생각하면 구분하는 게 맞는 듯
  • 결제, AI 테이블 - 생성만 / 수정, 삭제는 불가능할 것 같음

[241105 TIL] 

My Select Shop 프로젝트

  • 구현 기능 점검
  • 카카오 로그인 구현
  • Spring AOP, Timer 적용
  • 예외처리

구현 기능 점검

⚠️ 트러블슈팅 ⚠️

 

1. 문제 정의

  • 관심 상품 폴더 기능 점검중, 폴더 추가가 제대로 이뤄지지 않는 문제 발견
    • 관심 상품에서 폴더 추가 버튼을 누르면 작동하지 않음
    • 폴더 추가를 하면 중복하지 않는 폴더명임에도 중복된 폴더라는 알림이 뜨지만, 폴더 추가는 됨

 

2. 원인 추론

 

ERROR

org.thymeleaf.exceptions.TemplateInputException: Error resolving template [api/folders], template might not exist or might not be accessible by any of the configured Template Resolvers

 

 

 

1. thymeleaf exception 이 발생했기에 front 문제인가?

  • console 오류를 확인해보니 basic.js 파일의 folders.map 이 제대로 동작하지 않음을 확인
  • front 의 문제는 아니고, folder 를 제대로 넘겨받지 못하는 문제인듯함

 

2. FolderController 에 API 를 잘못 작성했나?

  • 구글링해보니 API 주소를 잘못 적은 경우가 다반사이길래 확인해보니, 모두 정확하게 적혀있음

 

3. FolderService 에 폴더 추가 함수 자체가 잘못 작성됐나?

  • 조회 함수에서 print를 찍어보니 folderList 가 제대로 생성되지 않음을 확인

  • 추가 함수에서 print를 찍어보니 print 안됨 -> addFolders 함수 안으로 들어가지 못함

 

➡️  folder 가 제대로 넘어오지 못함

 

 

4. FolderController 에서는 folder 가 제대로 생성되는지?

  • PostMapping 에서 print를 찍어보니 print 안됨

 

➡️ @RequestBody 가 제대로 동작하지 않음

 

 

5. @RequestBody 사용을 위한 애노테이션이 제대로 작성되어 있는지?

  • @Controller 만 작성되어 있음을 확인!!

 

3. 해결 방안 및 결과 

  • @Controller -> @RestController
    • @RequestBody 를 사용하려면 @RestController 혹은 @Controller + @ResponseBody 가 명시되어야 함!!
  • @RestController 변경 후 폴더 추가가 제대로 동작됨을 확인

 


카카오 로그인 구현

⚠️ 트러블슈팅 ⚠️

 

1. 문제 정의

  • 카카오 로그인 앱 관리자 설정 오류

 

2. 원인 추론

 

1. Redirect URI 가 잘못 작성되었나?

  • 카카오에 등록한 Redirect URI : http://localhost:8080/api/user/kakao/callback
  • KakaoService 에 작성한 Redirect URI : http://localhost:8080/api/user/login-page/api/user/kakao/callback

 

3. 해결 방안 및 결과

  • redirect_uri 수정
    • http://localhost:8080/api/user/login-page/api/user/kakao/callback
      -> http://localhost:8080/api/user/kakao/callback
  • 수정 후 카카오 로그인 성공!

 

+ Recent posts