하루 전 · 김혁진 님의 새로운 답변
nextjs middleware 에서 protected route 처리 하는 방법이 궁금합니다
middleware 에서 토큰 인증에 따른 redirect 를 구현 할려고 합니다 제가 생각한 로직은 인증이 필요한 페이지는 accesstoken을 쿠키에서 받아오고 토큰이 없거나, 인증이 실패하면 login 페이지로 이동, 토큰이 만료된 경우에는 refresh 요청이후 accesstoken,refreshtoken 재발급 이후 원래 이동할려는 페이지로 이동 이렇게 생각중인데 다만 하나 걸리는게 middleware에서 refresh api 요청을 하는게 과연 올바를까? 궁금합니다 그럼에도 굳이 middleware 에서 할려는 이유는 page단 에서 처리할경우에는 결국에는 한번 그 페이지로 이동했다가 처리되는거라 깜빡이는 이슈가 생겨서 그렇습니다 보통 어떤식으로 처리하는지 궁금해요
개발자
#react
#nextjs
#프론트엔드
#middleware
#token
답변 2
댓글 0
조회 55
4달 전 · 허니 님의 새로운 답변
Next.js 와 데이터 패칭 관련 React Query SSR
안녕하세요. Next.js 13.4 버전으로 개발중인 주니어 개발자입니다. SSR 관련해서 처음 접하고 개발중인데 Data Fetching 부분에서 조금 이론과 실무 모두 조금 막혀있습니다. 다름이 아니라 서버 컴포넌트/클라이언트 컴포넌트 이렇게 2개로 나뉘는데 accessToken 사용 떄문에 axios를 사용중입니다. 그래서 마이페이지 를 구현중에 데이터를 불러와서 뿌려주는 부분을 구현중인데 클라이언트 컴포넌트에서 useEffect 안에서 불러오면 한 박자 느리게 데이터가 뿌려져서 이질감이 있습니다. 그래서 서버컴포넌트에서 prefetch 해서 react query 사용해서 hydration 방식으로 직렬화 해서 내려주고 클라이언트 컴포넌트에서 const { data } = useQuery(['querykey'], () => queryFn) 형태로 사용해서 뿌려주고싶은데 여기서 이 'data'는 useState에 할당을 못하나요? 마이페이지 데이터 수정시에는 어떻게 활용을 해야되는건지 잘 모르겠습니다...
개발자
#nextjs
#nextjs13
#nextjs14
#reactquery
#서버컴포넌트
답변 1
댓글 0
보충이 필요해요 1
조회 76
4달 전 · 문종호 님의 새로운 답변
RAG 를 짜는 중에 도무지 어떤 부분이 문제인지 모르겠습니다.
# JSON 파일에서 FAQ 데이터를 로드하는 함수 def load_faq_data_from_json(file_path): with open(file_path, 'r', encoding='utf-8') as f: faq_data = json.load(f) return faq_data # FAQ 데이터 로드 json_file_path = '' faq_data = load_faq_data_from_json(json_file_path) # ChromaDB 클라이언트 및 Embedding 설정 chroma_client = chromadb.Client() # ChromaDB 클라이언트 생성 # 고유한 컬렉션 이름 생성 collection_name = "faq_data_" + datetime.datetime.now().strftime("%Y%m%d_%H%M%S") collection = chroma_client.create_collection(collection_name) # LangChain의 Text Splitter 설정 text_splitter = RecursiveCharacterTextSplitter( chunk_size=512, chunk_overlap=50 ) # OpenAI 임베딩 설정 openai_api_key = '' embedding_function = OpenAIEmbeddings( model="text-embedding-ada-002", openai_api_key=openai_api_key ) # 텍스트 스플리팅 및 임베딩 생성 함수 def split_and_embed_text(text): splitted_texts = text_splitter.split_text(text) print(f"Splitted texts: {splitted_texts}") try: # OpenAIEmbeddings는 embed_documents를 사용합니다. embeddings = embedding_function.embed_documents(splitted_texts) except Exception as e: print(f"임베딩 생성 중 오류 발생: {e}") return None # 임베딩이 제대로 생성되었는지 확인합니다. if embeddings is None or len(embeddings) == 0: print("임베딩 생성 실패") return None # 임베딩을 numpy 배열로 변환 embeddings = np.array(embeddings) print(f"Embeddings shape: {embeddings.shape}") # 임베딩 벡터의 차원을 확인하고 처리합니다. if embeddings.ndim == 1 and embeddings.shape[0] == 1536: # 임베딩이 1차원 배열이고 길이가 1536인 경우 final_embedding = embeddings elif embeddings.ndim == 2 and embeddings.shape[1] == 1536: # 임베딩이 2차원 배열이고 두 번째 차원이 1536인 경우 final_embedding = np.mean(embeddings, axis=0) else: print("임베딩 벡터의 차원이 예상과 다릅니다.") return None print(f"Final embedding shape: {final_embedding.shape}") return final_embedding # FAQ 데이터를 Vector DB에 저장 def store_faq_data_in_vector_db(faq_data, collection): for faq in faq_data: # 'question'과 'answer'가 있는지 확인하고, 'answer'가 None이 아닌지 확인 if 'question' not in faq or 'answer' not in faq or faq['answer'] is None: print(f"누락된 'question' 또는 'answer'로 인해 항목을 건너뜁니다: {faq}") continue # 다음 항목으로 넘어감 # 텍스트 스플리팅 및 임베딩 생성 question_embedding = split_and_embed_text(faq['question']) if question_embedding is None: print(f"Embedding generation failed for question: {faq['question']}") continue # 임베딩이 없으면 다음 질문으로 넘어감 print(f"Generated embedding for question '{faq['question']}': {question_embedding}") # 각 질문에 고유한 ID 생성 faq_id = str(uuid.uuid4()) # 메타데이터에서 None 값을 제거 metadata = {k: v for k, v in {"answer": faq['answer']}.items() if v is not None} # Vector DB에 저장 collection.add( documents=[faq['question']], metadatas=[metadata], ids=[faq_id], embeddings=[question_embedding] ) # 추가 후 임베딩 확인 (저장된 후 곧바로 확인) stored_results = collection.get(ids=[faq_id], include=["embeddings"]) if stored_results['embeddings'] is not None and len(stored_results['embeddings']) > 0: print(f"Embedding for question '{faq['question']}' successfully stored.") else: print(f"Failed to store embedding for question '{faq['question']}'") # FAQ 데이터를 JSON에서 로드하고 저장 store_faq_data_in_vector_db(faq_data, collection) 이렇게 데이터를 저장하고 # 환경 변수에서 API 키 로드 openai_api_key = os.getenv("OPENAI_API_KEY") if not openai_api_key: raise ValueError("OpenAI API 키가 설정되지 않았습니다. 환경 변수 OPENAI_API_KEY를 설정하세요.") # OpenAI 임베딩 설정 embedding_function = OpenAIEmbeddings( model="text-embedding-ada-002", openai_api_key=openai_api_key ) # LangChain의 Text Splitter 설정 (일관성 유지) text_splitter = RecursiveCharacterTextSplitter( chunk_size=512, chunk_overlap=50 ) # ChromaDB 클라이언트 및 컬렉션 설정 chroma_client = chromadb.Client() collection_name = "faq_data_collection" try: # 이미 존재하는 컬렉션인지 확인하고, 있으면 가져옴 collection = chroma_client.get_collection(name=collection_name) except chromadb.errors.CollectionNotFoundError: # 컬렉션이 존재하지 않을 경우에만 생성 collection = chroma_client.create_collection(name=collection_name) # Vector DB에서 유사 질문 검색 (ChromaDB) def find_similar_question_in_vector_db(new_question_embedding, collection, k=5): results = collection.query(query_embeddings=[new_question_embedding], n_results=k, include=['documents', 'metadatas', 'embeddings']) best_similarity = 0 best_question = None best_answer = None # 검색 결과에서 각 질문의 유사도와 답변을 처리합니다. if 'documents' in results and 'metadatas' in results: documents = results['documents'][0] metadatas = results['metadatas'][0] embeddings = results['embeddings'][0] for i in range(len(documents)): stored_embedding = embeddings[i] metadata = metadatas[i] if stored_embedding is not None: # 코사인 유사도를 통해 유사도를 계산합니다. similarity = cosine_similarity([new_question_embedding], [stored_embedding])[0][0] print(f"유사도: {similarity} for {documents[i]}") # 유사도가 가장 높은 결과를 선택하며, 임계값 이상일 경우에만 선택 if similarity > best_similarity and similarity >= SIMILARITY_THRESHOLD: best_similarity = similarity best_question = documents[i] if isinstance(metadata, list): metadata = metadata[0] best_answer = metadata.get('answer') if isinstance(metadata, dict) else None return best_question, best_answer # Fine-tuned GPT를 사용해 새로운 답변 생성 def gpt_generate_response_from_finetuned_gpt(question, style="의사 A 말투"): prompt = f"다음은 환자의 질문입니다: \"{question}\". 아래 말투를 사용하여 질문에 대해 성실하고 정확한 답변을 작성해주세요.\n\ 말투: {style}" response = client.chat.completions.create( model="", # Fine-tuned된 GPT 모델 ID messages=[ {"role": "system", "content": "You are a helpful medical assistant."}, {"role": "user", "content": prompt}, ], max_tokens=300, temperature=0.7, # 답변의 다양성을 조절합니다. ) return response.choices[0].message.content.strip() # 새로운 질문 처리 및 최종 응답 생성 def generate_final_response(new_question, collection): # 텍스트 스플리팅 및 임베딩 생성 splitted_texts = text_splitter.split_text(new_question) new_question_embedding = np.mean(embedding_function.embed_documents(splitted_texts), axis=0) # ChromaDB에서 유사 질문 검색 similar_question, answer = find_similar_question_in_vector_db(new_question_embedding, collection) if similar_question and answer: final_response = f"질문: {new_question}\n유사 질문: {similar_question}\n기본 답변: {answer}" else: generated_answer = gpt_generate_response_from_finetuned_gpt(new_question) final_response = f"질문: {new_question}\nGPT로 생성된 답변: {generated_answer}\n(이 답변은 벡터데이터에서 유사한 답변을 찾을 수 없어 GPT에 의해 생성되었습니다.)" return final_response # 사용자로부터 새로운 질문 입력 받기 new_question = input("새로운 질문을 입력하세요: ") # 최종 응답 생성 response = generate_final_response(new_question, collection) print(response) 로 데이터베이스에서 유사한 질문-답변 쌍을 끌어오려는데 정확히 같은 질문을 넣어도 (이러면 유사도가 1인데) 저장되어있는 답변이 끌어와지질 않네요...
개발자
#llm#rag
답변 1
댓글 0
조회 74
6달 전 · 익명 님의 질문
OAuth2 + jwt 환경 부하 테스트 방법에 대한 질문..
최근 성능 테스트의 중요성에 대해 알게 되어서 목표 성능치를 두고 부하테스트를 진행해보려는 계획에 있습니다! 테스트 툴로는 nGrinder를 사용할 생각인데요, 문제는 제 서버가 이메일 로그인을 지원하지 않고 oauth2와 jwt를 활용한 인증/인가 방식을 사용하는데 부하테스트 시 가상 유저에게 어떻게 accessToken을 발급해주어야 하는지에 대한 궁금증이 생겼습니다..! 제가 생각해본 방식들은 다음과 같습니다. 1. 실제 유저에 대한 accessToken을 하나 발급해두고 이를 고정값으로 사용한다. - 이 방식은 제일 편하지만 사실상 한명의 유저에 대한 시나리오만 테스트할 수 밖에 없고, 같은 유저에 대한 각종 캐싱된 데이터들로 인해 실제 상황과는 동떨어진 작업이 될 것 같아 채택하지 않았습니다. 2. FakeAuthServer와 같은 가상의 OAuth 서버를 만들어 로그인을 시도한다. - 구현하기는 어려워보이지만 그나마 가장 실제 서비스와 동일한 형태입니다. 하지만, 제가 테스트하려는 시나리오는 여러 요청에 대한 순차적인 테스트가 아닌 하나의 API가 얼마나 많은 부하를 견딜 수 있는지 보기 위한 테스트라서 굳이 로그인 과정을 테스트에 포함시킬 필요는 없어보입니다.. - 사실 하나의 API에 대한 테스트만 진행해도 괜찮은지 몰라서 이 방법을 버리지 못하고 있습니다 3. nGrinder의 테스트 스크립트에서 @BeforeThread에 jwt를 발급받는 로직을 작성해서 테스트 전 미리 토큰을 발급받아 요청한다. - 이 방식은 로그인 과정은 포함되어 있지 않고 이미 토큰을 발급받았다는 가정하에 하나의 API만 테스트하기 가장 적합한 방법이라고 생각이 되었습니다. - 번거롭지만 jwt를 직접 생성해주기 위해 jjwt 라이브러리를 nGrinder에 포함시켜야 될 것 같습니다 - 하지만 이렇게 스크립트에서 토큰을 발급해주는게 맞는지 실무에서도 이런식으로 사용하는 경우가 있는지 궁금합니다.. 처음 부하 테스트를 적용하려고 하는데 oauth2 + jwt로만 구성된 예제가 보이지 않네요 ㅠㅠ 어느 방법이 가장 적절한지 혹은 더 나은 방법이 있는지 조언을 구하고자 질문 남깁니다!
개발자
#ngrinder
#oauth
#jwt
#부하테스트
#성능테스트
답변 0
댓글 0
조회 102
7달 전 · 상우기 님의 질문 업데이트
Nextjs14 서버 컴퍼넌트 JWT 갱신 방법 문의
안녕하세요 NextJS14 에서 JWT 로그인 방식으로 프로젝트 진행중에 있습니다. 현재 AccessToken 만료시 재 갱신하는 로직을 하면서 해결하지 못하는 내용이 있어서 문의 드리립니다. 서버 컴포넌트와 클라이언트 컴포넌트에서 갱신된 AccessToken 을 공유 하는 법에 대해서 어떻게 처리 하셨나요? - app router 사용 - accessToken, refreshToken 쿠키 사용 - fetch 를 이용하여 API 호출 아래 테스트 내용으로 서버 컴포넌트에서 AccessToken 만료되어 갱신되는 경우 클라이언트로 쿠키를 갱신해줄 방법을 모르겠습니다. 너무 CSR 구조로 생각하는거 같기도해서, 이런 경우 어떻게 토큰을 현행화 해서 사용하는지 문의 드립니다. 별도 가이드 문서를 더 찾아보면 서버 컴포넌트에서는 쿠키를 사용하지 말라는 글도 보여서, 방향성을 잘못잡고 있는 느낌도 들고 있습니다. 많은 조언 부탁드립니다!! 테스트 케이스) 1. 서버 <-> 클라이언트 (에러) - 서버 컴포넌트에서 백엔드 API 호출 -> 토큰 만료 -> AccessToken 재 갱신 API 호출 -> 쿠키 set -> 클라이언트에서 백엔드 API 호출(당연히 클라이언트에서는 쿠키가 갱신안되서 에러) 2. 서버 <-> 서버(성공) - 서버 컴포넌트에서 백엔드 API 호출 -> 토큰 만료 -> AccessToken 재 갱신 API 호출-> 쿠키 set -> 서버 백엔드 API 호출 3. 클라이언트 <-> 클라이언트 (성공) - 클라이언트 컴포넌트에서 백엔드 API 호출 -> 토큰 만료 -> AccessToken 재 갱신 API 호출-> 쿠키 set -> 클라이언트 백엔드 API 호출
개발자
#nextjs
#jwt
#accesstoken
#refreshtoken
#nextjs14
답변 0
댓글 0
조회 80
7달 전 · 익명 님의 질문
웹뷰 auth 처리 질문입니다
안녕하세요, React native에서 각 탭들이 서로 다른 웹뷰를 사용하고 있습니다. 한 탭에서 accesstoken을 refresh를 하고 있는 상태에서 다른 탭에 들어갈 경우 refresh token이 갱신되지 않은 상태에서 요청을 보내 동시성 이슈(race condition)가 발생할 수 있을 거 같은데 어떻게 해결해야 할까요? 그냥 단일 웹일 때에는 axios interceptor에서 큐에 넣어서 해결했는데.. 토큰을 갱신해야 할 때마다 앱단으로 보내준 다음에 거기서 큐로 처리하고 완료되면 각 웹뷰로 뿌려주는 방식으로 가야 하려나요? 현직에 계신 분들 웹뷰 auth 어떻게 처리하시나 궁금합니다.
개발자
#fe
#react
#reactnative
답변 0
댓글 0
조회 56
8달 전 · 김인후 님의 새로운 답변
spring security에서 JWT를 사용할 때 질문이 있습니다.
SecurityConfig에서 .requestMatchers(HttpMethod.GET, "/boards/*/comments").permitAll() 이런 식으로 허용을 해주고 JwtAuthorizationFilter에서 accessToken이 유효하지 않으면 response에 토큰에 문제가 생겼다는 에러 메세지를 리턴을 하게 해뒀습니다. GET /boards/*/comments 요청을 보내면 해당 게시물의 댓글들을 조회를 해올 때 좋아요를 누른 상태인지 누르지 않은 상태인지 구분을 할때 문제가 생겼습니다. 로그인을 한 사용자는 댓글들을 조회할 때 좋아요를 눌렀나 안눌렀나 확인을 해야하고 로그인을 하지 않은 사용자는 무조건 좋아요를 안 누른 상태로 해야되는데 JwtAuthorizationFilter에서 에러 메세지를 리턴을 하되면 로그인을 해야지만 조회가 되는 문제가 생기고 JwtAuthorizationFilter에서 에러 메세지를 리턴하는 코드를 빼자니 모든 Controller쪽에서 null체크를 해줘야 하고... 감을 못잡겠습니다ㅜ_ㅜ
개발자
#java
#spring
답변 1
댓글 0
조회 59
9달 전 · 지욱 님의 질문 업데이트
tensorflow.keras
import tensorflow.keras as keras from keras.models import load_model from tensorflow.keras.preprocessing.text import Tokenizer from tensorflow.keras.preprocessing.sequence import pad_sequences from hanspell import spell_checker tersorflow랑 keras를 설치했는데, 개별적으로 할 때는 잘 되는데 tensorflow.keras는 오류가 생기네요 ㅠㅠ 그리고 keras.models도 안되네요 ㅠㅠ 마지막으로 hanspell은 정확히 어떻게 설치해야 될까요
개발자
#tensorflow
답변 0
댓글 0
조회 44
10달 전 · 익명 님의 질문
JWT invaild signature 오류
쿠키에 accessToken이 발급이 되고 있고 데이터 베이스에 refreshToken이 발급 되고 있습니다 근데 사용자 조회를 하려고 api코드를 작성하니 계속 invalid signature 오류가 나오네요 시크릿 키도 확인 해봤지만 그건 문제가 아니였어요... 혹시 몰라 깃허브 코드 남겨둡니다... 문제를 해결해 주실 능력자 찾아요.... https://github.com/LeeWinJun/nikeShop
개발자
#토큰-오류-
#jwt
#풀스택
#프론트엔드
#백엔드
답변 0
댓글 0
조회 61
10달 전 · 지민성 님의 질문
React Spring 배포과정 중 의문의 404
react + spring boot로 진행하는 프로젝트가 현재 cloudtype이라는 플랫폼으로 배포중에 있습니다. 문제는 정확한 서버주소를 호출하는 것 같음에 불구하고 404 에러가 발생하여 해결하지 못하고 있습니다. 현재, 아래 사진과 같은 로그가 클라이언트, 서버에 각각 발생합니다. 서버에서는 다음과 같이 구성되어있고 @RestController @RequestMapping("/v1/login") @RequiredArgsConstructor @CrossOrigin(origins = "https://web-secondchance-front-bug-1cupyg2klvnmgdft.sel5.cloudtype.app") public class KakaoController { private final KakaoService kakaoService; private final Logger LOGGER = LoggerFactory.getLogger(KakaoController.class); @PostMapping("/kakao-login") public ResponseEntity<UserDto> kakaoLogin(@RequestBody KakaoLoginDto kakaoLoginDto) { String code = kakaoLoginDto.getCode(); LOGGER.info("Get Code from FrontEnd : {}", code); LOGGER.info("Request getAccessToken()"); kakaoLoginDto = kakaoService.getAccessToken(code); String accessToken = kakaoLoginDto.getAccess_token(); LOGGER.info("access_token : {}", accessToken); if(accessToken != null){ UserDto userDto = kakaoService.getUserInfo(accessToken); return ResponseEntity.ok(userDto); } else { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null); } // accessToken이 null임에도 getUserInfo를 부름. // 안부르게 끔 위의 방법을 포함하여 // 1. map에서 true, false를 사용하여 해봄 // 2. getAccessToken을 map객체로 반환하게끔 하여 accessToken이 있으면 true, 없으면 false로 하여 isEmpty 함수로 체크하여 부름 // 위의 두 방법 전부 소용없음. 그냥 getUserInfo를 부름. } @PostMapping("/kakao-logout") public String kakaoLogout(){ return "ok"; } } 현재 리액트에서는 다음과 같이 axios.post로 접근하여 code를 전달합니다. 무엇이 문제일까요?
개발자
#react
#spring-boot
#배포
#404
답변 0
댓글 0
추천해요 1
조회 147
일 년 전 · 안희수 님의 새로운 답변
React JWT 재갱신 방법이 또 있을까요?
안녕하세요 회사에서 기존 인증시스템을 개편하면서 프론트에서 JWT를 관리하게되었는데 현재 axios intercepter response를 통해서 재갱신을 하고 있는데 기존로직과 충돌되는 부분이 많아 재갱신이 안될때가 있었습니다. 현재 access token은 store에 저장되고 있고, refresh token은 쿠키에 저장되고 있어서 새로고침시에 refresh token을 통해 갱신하고있습니다. 그런데 현재 재갱신 방법을 바꾸고싶은데 혹시 axios intercepter말고 다른 방법은 없을까요? 현재 고려중인 방법은 커스텀훅, HOC 구조로 개편하는 방법을 생각중인데 다른 방법이 있는지 궁금합니다.
개발자
#react
#jwt로그인
#jwt
#redux
답변 1
댓글 0
조회 95
일 년 전 · 박정환 님의 답변 업데이트
JWT에서 refresh_token을 넘겨줄때 어떡해 넘겨주면 좋을까요?
로그인을 했을 때 access_token, refresh_token을 받아서 클라리언트에서 쿠키로 저장을 했습니다. access_token이 만료됬을 때 refresh_token을 넘겨줘야 하는데 이 부분에서 궁금한게 있습니다. 만약에 글쓰는 부분같이 access_token이 필요한 부분에서 access_token이 만료된 경우에 refresh_token을 넘겨주고 access_token을 다시 받아오는데 이미 여기서 글쓰기는 access_token이 없어서 실패하는 거잖아요. 그러면 다시 글쓰기를 시도해야 하는건가요? 아니면 access_token이 없어지고 refresh_token을 줘서 받아오는게 아니라 access_token이 만료 기간이 다가오면 넉넉하게 잡아서 refresh_token을 줘서 받아오는건가요??
개발자
#쿠키
답변 2
댓글 0
조회 132
일 년 전 · 김현수 님의 새로운 댓글
토큰값을 받아오지 못하는 문제 (undefined)
안녕하세요 JWT 토큰을 이용해 로그인 검증하는 로직을 구현하고 있습니다. 로컬스토리지에 토큰을 저장하는 것까지 성공했으나 프론트 측에서 로그인 검증을 요청할때 실제 토큰 값을 받아오지 못하는 문제가 있어 질문 드립니다. login-required에서 토큰 값 유무 로직을 전부 지우고 콘솔로만 찍는 경우 undefined와 실제 토큰값이 나타납니다. 만약 토큰 값 유무 로직을 이용한다면 undefined값만 서버로 들어와 페이지가 무한로딩 되는 현상이 나타납니다. next()처리가 안되기 때문인 것 같습니다. (+ index.html은 test.js를 연결하고 있습니다.) 사진으로 보면 네트워크 요청헤더에서 확인한 결과 1. 처음엔 document 유형의 localhost를, (인증 헤더 x) 이후 js를 불러온다 2. 마지막에 xhr형식인 localhost를 불러옵니다 (인증 헤더 o) (여기서 undefined, 실제 토큰값이 콘솔에 동시에 나타나는 이유라고 생각이 듦) (순서를 보면 document 유형 localhost -> css, js -> xhr 유형 localhost 즉 처음에 document 유형에서 인증헤더를 못가져와서 (js가 로드되기 전이여서) 토큰 유무를 체크하지 못하는 것 같습니다) 결론적으로 제가 생각한 문제 분석 (1) ('/') 에 get 요청을 보낸다. (2) 서버는 loginRequired를 실행한다. (3) 서버로 부터 html을 받지 못한 상태에 loginRequired가 실행되어 토큰 값은 undefined가 된다. (4) next()를 거쳐 서버에서 html을 클라이언트로 부터 응답을 해준다. (5) html을 브라우저에 보여주면서 그 html에 연결된 js를 불러온다. (6) 이때 불러온 test.js에서 get요청 ('/') 로직을 불러와 다시 server.js에서 loginRequired 응답으로 토큰 값을 불러온다. 즉 js가 로드가 되어야 userToken을 로컬스토리지로 부터 받아오고 요청을 하여 토큰 값을 불러올 수 있다. 그런데 get 요청전에 토큰 검증을 하고 허가가 되어야 html을 로드해야 하지 않을까? 그렇다면 서버에서 처리를 해야하는가? 배워가는 학부생으로 많이 부족하다고 생각합니다,, 선배님들의 견해를 받고 싶어 게시물 올립니다..! 핵심 코드는 다음과 같습니다.
개발자
#javascript
#node.js
#axios
#rest-api
답변 2
댓글 2
조회 161
일 년 전 · 안희수 님의 답변 업데이트
NextJS 14에서 JWT를 쿠키를 통해 관리하려고 하는데 서버에서 set-cookie 해주는 방식말고 route 핸들러에서 주입할수는 없나요?
안녕하세요. 최근 NextJs를 공부하며 이전 리액트 기반의 사이드 프로젝트를 NextJs로 구현해보고 있습니다. 카카오 로그인만 지원을 하고 있고, 프론트 쪽에서 카카오 인가 코드를 백엔드로 넘기면 백에서 jwt를 발급해서 응답으로 access token과 refresh token을 프론트로 넘겨주고 있습니다. 이전 프로젝트에서는 두 토큰 모두 localStorage에 저장하는 방식으로 했었는데요, 이번에는 쿠키를 이용해보려고 하고 있습니다. 다만 백엔드에서 set-cookie를 해놓지 않아서 응답으로 받은 토큰을 따로 쿠키에 저장해야하는 상황입니다. 하지만 Server Component에서는 set cookie가 안되는 것으로 알고 있습니다. <목표 구현 방식> route handler를 통해서 백엔드 api를 호출하고 그 값을 쿠키에 저장하도록 코드를 짰습니다. (/app/api/token/route.ts) return 값은 확인을 위해서 임의로 넣었습니다. 그리고 쿠키에 저장된 토큰을 통해서 서버 컴포넌트에서 이를 이용해 백엔드 api 통신을 하고 싶습니다. 하지만 서버 컴포넌트에서 쿠키를 확인하니 비어있는 쿠키인 것을 알 수 있었습니다. 얕은 지식으로 생각을 했을때, (route handler - 브라우저 혹은 서버 컴포넌트)에서 생성한 쿠키는 (백엔드 도메인 - 브라우저 혹은 서버 컴포넌트) 통신에 사용되는 쿠키와 다르기 때문이라고 생각이 들었는데 해답을 찾지 못했습니다. <질문 사항> - 백엔드 서버에서 set-cookie를 하지 않고 직접 구현할 순 없을까요? 쿠키는 forwarding이 안되나요? - 제가 생각한 구조 말고 추천하시는 토큰 관리 방식에 대해서 알려주셔도 감사하겠습니다. 아직 초보 개발자에 글도 잘 쓰지 못해 이해하시기 힘들 것 같지만, 넓으신 아량으로 지식을 나눠주신다면 정말 큰 도움이 될 것 같습니다. 긴글 읽어주셔서 감사합니다 (_ _)
개발자
#next.js
#jwt
#react
#front-end
#cookie
답변 1
댓글 0
추천해요 1
조회 1,006
일 년 전 · 안희수 님의 답변 업데이트
JWT 토큰 중 accessToken은 어디에 보관하는 것이 좋을까요?
안녕하세요 jwt 토큰 보관에 대해 질문 있습니다. 원래는 accessToken은 로컬스토리지에, refreshToken은 httponly cookie로 보관하려 했습니다. 하지만 accessToken을 로컬스토리지로 보관하면 XSS 공격에 취약하다라는 단점 때문에 로컬 변수를 사용하라는 글도 종종 보이더라구요. 어떤 방식을 사용하는게 좋은 방법일까요? 퍼널 형식의 웹페이지며, 이메일 인증을 통해 토큰을 발급합니다. acceToken의 만료 시간은 30분정도로 생각중입니다.
개발자
#react
#jwt토큰
#accesstoken
#cookie
#localstorage
답변 1
댓글 0
추천해요 1
조회 309
일 년 전 · 허니 님의 새로운 답변
리액트 로그인질문..
react + 파이어베이스만 써오다가 react + express 조합을 오랜만에 사용중인데 긴가민가한점이있어서 질문드립니다 ㅠㅠ import axios from 'axios'; const instance = axios.create({ baseURL: process.env.REACT_APP_API_BASE_URL, timeout: 2500, headers: { 'Content-Type': 'application/json', withCredential: true, }, }); instance.interceptors.request.use( (config) => { const token = localStorage.getItem('token'); if (token) { config.headers['Authorization'] = token; } else { delete config.headers['Authorization']; } return config; }, (error) => { return Promise.reject(error); } ); export default instance; 이렇게 인터셉터를주어서, 요청할 때마다 토큰을 전달하고있습니다. 그리고 프라이빗 라우터 + 유저정보 인증 훅을 사용해서 로그인사용자만 접근가능하게 페이지를 설정해줬습니다. 근데 질문 1. 네트워크탭 Request Headers 에서 Authorization을 확인해보면 토큰정보가 그대로 노출되고있는데요 원래 이렇게되나요? 질문 2. Bearer + token 이렇게 보내는 경우는 포스트맨이나 이런걸로 테스트할때만 Bearer 을 붙여서 보내주면될까요? 질문 3. 검색 키워드가 생각이안나서 질문으로 올립니다. 아주 옛날에는 (4년전) App.tsx에서 if(localstorage.token){ setAuthToekn(token); } 이런식으로 하고, setAuthToken함수는 import axios from 'axios'; const setAuthToken = (token) => { if (token) { axios.defaults.headers.common['x-auth-token'] = token; } else { delete axios.defaults.headers.common['x-auth-token']; } }; export default setAuthToken; 이런식으로 되어있었는데요, 요즘은 제가 짠 코드처럼 axios.인터셉터 식으로 하는게 맞나요? 질문 4. 그럼 요즘도 회원가입/로그인시 로컬스토리지에 유저 정보 (닉네임 이름 이메일, 토큰정보)만 저장해두고 로그인하면, 로그인버튼이 회원 닉네임으로 변하게 해준다던가.. 이런식으로 분기처리를 하나요? ( 저는 이렇게하고있어서요.. 로딩처리를 줄수도있겠지만 깜빡거리는게 싫고, 또 로컬스토리지로안하면 로그인버튼으로 잠깐바꼇다가 회원닉네임이 표시되더라구요) 질문5. (질문4와 이어집니다.) 만약 질문4처럼하면 사용자가 사이트에 계속 로그인중인데, 이 토큰이 끝났는지 판단하려는 코드를 따로 작성해줘야할까요? 예를들면, App.tsx에 서버 api/auth같은거에 요청보내는 로직을 작성해서, 토큰만보내서 유효한 토큰인지 아닌지, 유효하지않은토큰이면 에러를 리턴시켜준다던가, 리프레쉬토큰을 발급시켜서 연장시켜준다던가 이런식으로하면될까요? 마지막으로 질문이 좀 많고 중구난방인데 죄송스럽고 조심스럽네요..
개발자
#react
#login
#register
#local-storage
#jwt
답변 1
댓글 0
조회 108
일 년 전 · 최성민 님의 새로운 댓글
Nextjs app router middleware + token 여부에 따른 리다이렉트
안녕하세요, next.js로 팀 프로젝트 진행 중 궁금한 것이 생겨 질문드립니다. next.js의 middleware.ts를 이용하여 모든 라우터에 접근할 때마다 유저 인증 토큰을 확인 후, 토큰이 없으면 /login 페이지로, 토큰이 있다면 원하는 페이지로 이동할 수 있도록 처리하길 원합니다. 유저 토큰은 로그인 시, access token을 body로 내려 받아 전역 utils 파일에 클래스 형태로 저장하고 있고, refresh token은 쿠키로 내려 받아 필요할 때마다 토큰 재발급 요청을 보낼 수 있도록 설계하고 있어요. 그런데 middleware.ts에서 전역으로 관리하는 토큰에 접근이 불가능한 것 같더라구요.. accessToken을 쿠키로 관리하지 않으면 미들웨어에서 토큰에 접근하는 방법이 아예 없는 것일까요? 아니면 제가 뭔가 단단히 착각하고 있는 것이라면 도움을 요청하고 싶습니다! 감사합니다🙇♂️
개발자
#next.js
#app-router
#token
#middleware
#cookie
답변 2
댓글 1
조회 628
일 년 전 · 삥 님의 새로운 댓글
[React] 도움!! 같은 함수 2번 실행하는 방법
안녕하세요, 스타트업에 취업한 신입 프론트 개발자입니다. 지금 회사에서 jwt 토큰으로 로그인을 구현하고있는데, 지금 3일째 붙잡고있는데 전혀 해결이 안되서 너무 막막합니다 ... 페이지가 처음 열릴 때 load_board()라는 함수를 실행합니다. 이는 axios 통신을 하는 함수이고 만약 res.data=== 'reload' 라면 refresh_token()함수를 실행한 후 다시 load_board()를 실행하고 싶습니다. 이걸 어떻게하면 좋을까요 ?... 제가 해봤던 방법은 1번 .then((res) =>{ setIsRefresh(true); } useEffect(()=>{ if(isRefresh){ refresh_token(); setIsRefresh(false); load_board() },[isRefresh]) 이 방법은 되긴되나 서버와 통신을 최소 3번씩하고 ... (refresh_token()를 실행하기전에 자꾸 load_board()를 실행해서...) 2범 async await을 써보니 useEffect(()=>{ const res = load_board(); if(res.data ==='reload'){ await refresh_token(); await load_board} ... },[]) 이건 확실히 한번만 실행이되는데 refresh_token()의 리스폰이 오기전에 load_board()를 실행하니까 의도한대로 안돼요 . . . . . . . . 이걸 어쩌면 좋을까요. . . . . .
개발자
#react
#로그인
#jwt
#비동기
답변 4
댓글 7
조회 394
일 년 전 · 여진석 님의 새로운 댓글
nextJS 에서 안전하게 token 처리하기
nextjs에서 nextAuth 쓰지않고 안전하게 token 처리하는 완벽한 예시가 있는지 알고싶습니다. 사이드 프로젝트중에 여러 시도를 해봤는데 정답을 못찾겠습니다. 일단 axios 인터셉트로 ssr이나 csr이나 모두 토큰을 헤더에 담아서 보내는 것을 목표로 하고 있습니다. 1. 상태관리 라이브러리를 사용한다. 당연히 ssr 환경에서는 불가하니 탈락 2. 그냥 쿠키를 사용한다 보안 문제가 있으니 탈락. 3. http only 쿠키를 사용한다. csr 환경에서 접근할 수 없으니 탈락. 대안으로 생각해본 방법들은 1. 모든 api를 server action을 랩핑해서 미들웨어처럼 사용하고 http only 쿠키 이용하기 2. 쿠키와 상태관리 모두 값을 넣어두고 두가지 다 관리하면서 서버와 클라이언트 컴포넌트에서 각각 제어하기 하지만 두가지 방법은 너무 번거롭고 버그 양산일 것 같습니다. 많은 분들께 여쭤봤을 때는 그냥 쿠키를 사용하고 보안은 어느정도 포기한다는데 다른 방법이 있을까요?
개발자
#next.js
#react
#jwt
답변 1
댓글 6
추천해요 1
조회 1,046
일 년 전 · 이정윤 님의 답변 업데이트
Next.js에서 클라이언트 컴포넌트와 서버 컴포넌트의 axios interceptor 동기화
안녕하세요 Next.js 13버전 page router방식으로 개발중입니다. 클라이언트 컴포넌트와 서버 컴포넌트에서의 통신을 위해 각각 axios interceptor를 구현했습니다. 각각 store와 cookie에서 accesstoken값을 헤더에 넣어주는 역할을 하고 있는데 문제가 되는 부분은 토큰 만료 이후 갱신하는 부분입니다. interceptor가 두개이다보니 처음에는 서로 동일한 토큰응 가지고 있지만, 만약 클라이언트 컴포넌트에서 요청시 토큰이 만료되면 갱신하는 요청을 보내고, 서버 컴포넌트에서 요청시 만료되면 갱신하기 때문에 서로 일치하지 않는, 유효한 토큰이 두개가 되는 상황입니다. 현재 서버에서는 유효한 토큰이 하나만 존재하도록 설계를 해놓진 않아서 작동하는데 문제는 없지만 많이 찝찝하네요. 혹시 좋은 방안이 있을까요? 혹은 비슷하게 구현하신 분들의 상황을 공유 받을 수 있을까요?
개발자
#react
#next.js
답변 2
댓글 11
추천해요 3
조회 1,294
일 년 전 · 익명 님의 질문 업데이트
Python Keras 딥러닝
1. 제가 법을 딥러닝 시켜봤는데 출력물이 이상했거든요? 그래서 이 순서가 맞나요? - 자료 전처리 - 자료 tokenizing - 딥러닝 2. 딥러닝 시킬때 일반 채팅 ai는 Q&A 형식으로 딥러닝 하던데 이 법 조항은 Q&A 형식 말고 tokenizing 된 자료만 딥러닝 해야하나요? 딥러닝이 다 된 상태라고 가정했을때 Q. 헌법 몇조 몇항은? A. ~~~에요. Q. ??에 따르면 ??는 몇년 이하의 징역에 처해? A. ~~~년 이하의 징역에 처해요 이런식으로 출력되었으면 좋겠어요 제가 시도했던 방법은 후자이고 전자로 하려면 제가 임의로 Q&A 를 제작해야하나요?
개발자
#python
#keras
답변 0
댓글 0
조회 49
2달 전 · 민호 님의 새로운 댓글
Next.js app router의 쿠키값을 어떻게 세팅해야 할까요?
Next.js app router에서 쿠키로 JWT로그인을 사용 하고 있습니다. 서버는 백엔드 api 서버가 별도로 존재하는 상황입니다. 현재 인증 기반 api를 호출을 할 때, 만약 해당 accessToken이 만료가 됐다면 재발급을 해주는 백엔드 api를 통해 새로운 accessToken을 브라우저에 업데이트하는 로직을 구현하려고 했습니다. 클라이언트 컴포넌트에서는 전혀 문제가 없었습니다. 어차피 set-cookie를 백엔드에서 해주면 알아서 브라우저에 반영이 되니까요. 근데 문제는 서버 컴포넌트에서 동일한 요청을 하는 경우입니다. 동일하게 재발급 요청을 보낸 다음 set-cookie를 백엔드에서 해줘도 어차피 서버 컴포넌트에서 api를 쐈던것이기 때문에 그 반환값이 서버 컴포넌트로 오게 되고, 이는 브라우저에 반영이 안 되는데요ㅠ 혹시 이럴 경우에는 어떻게 처리를 하는게 좋을까요? 미들웨어나 라우트 핸들러를 사용하려 해도 그 방법을 도저히 모르겠네요
개발자
#next.js
#jwt
#react
#auth
#cookie
답변 1
댓글 1
추천해요 2
조회 360
일 년 전 · 백승훈 님의 답변 업데이트
React json load error
Data.json을 아래와 같이 설정하고 [ {"id": 1, "name": "kim", "age": 30}, {"id": 2, "name": "lee", "age": 25}, {"id": 3, "name": "park", "age": 35} ] 리액트 app.js에서 json을 불러 출력하려고 하면 아래와 같은 에러가 나와요 SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON 아무리 검색해도 해결법을 못찾겠어서 글 올립니다ㅠㅠ 아래 스크립트는 app.js 작성한 내용입니다 ㅠ
개발자
#react
#json
#promise
#javascript
답변 2
댓글 0
조회 172
일 년 전 · 익명 님의 질문
리액트 재사용 에러 처리 질문 있습니다
import해서 getAccessToken와 loginVerification를 사용중입니다. 그리고 이 코드를 다른 곳에서 import해서 ----중략---- try { const responseData = await sendApiRequest( apiUrl , { --생략-- }, 'POST'); ----Data(responseData.data); } catch (error) { ----중략---- 으로 import해서 사용 중입니다. 에러에 대한 처리 방법이 제대로 되었나요?
개발자
#react
답변 0
댓글 0
조회 42
일 년 전 · 장훈 님의 새로운 답변
postman api error : aborted
안녕하세요 국비 학원 다니는 비전공자 학생입니다.. 선생님들 정말 별거 아닌걸로 질문하는 것처럼 보이시겠지만 프로젝트 마감일이 얼마 안남았는데, 선생님께서는 바쁘셔서 봐주시지도 않고.. 에러가 나서 너무 막막해서 올려요.. 현재 스프링부트, jwt 사용중이고 토큰도 authorization bearer Token에 입력했습니다.. post 는 문제없이 되는데 다른 get에서만 계속 저런 에러가 떠요... 왜 그런건가요 ㅠㅠㅠ 혹시라도 문제 확인을 위해 더 확인이 필요한 부분이 있다면 추가적으로 첨부하겠습니다...!! 제발 도와주세요
개발자
#error
#springboot
#api
#backend
#postman
답변 1
댓글 0
조회 147
일 년 전 · 김태우 님의 새로운 답변
access token을 쿠키에 저장하는 작업은 프론트/백 어디서 해야 하나요?
안녕하세요. 사이드 프로젝트 리팩토링을 하는 중에 궁금한점이 생겨 질문 올립니다. 지금은 로그인 시 rt를 쿠키에 저장(백엔드에서), at를 로컬스토리지에 저장(프론트에서)하고 있습니다. 프론트측에선 api를 호출할 때마다 로컬스토리지에 있는 at를 꺼내서 fetch옵션에 전달해주는 작업을 하고 있어요. 그런데 서버 컴포넌트에서 api를 호출하려고 하니 로컬스토리지에 접근하지 못하는 문제가 있더라구요. 결국 at를 로컬스토리지가 아닌 쿠키에 저장하는 방식으로 변경하기로 했는데 이럴경우 at를 쿠키에 저장하는 작업을 백엔드와 프론트엔드 중 어느쪽에서 수행해야 하나요? 아니면 혹시 쿠키에 저장하는 방법 말고도 더 좋은 방법이 있을까요..?
개발자
#nextjs13
#jwt
답변 1
댓글 0
조회 393
일 년 전 · 장성호 님의 답변 업데이트
jwt 리플레시 토큰은 어디서 언제 데이터베이스에 저장할까요?
사수가 없는 상태에서 블로그 글들을 보고 어떻게 어떻게 jwt 토큰 발행까지 해냈습니다. 1차 로그인 하면 아이디 비밀번호를 받고 아이디로 검증후 토큰을 발급해서 웹페이지로 전달했는데요 블로그에는 그 추후의 로직에 대한 설명을 찾기가 어렵더라구요 ㅠ JwtTokenProvider 클래스에서 generateToken 메서드에서 에세스 토큰과 리플레시 토큰을 생성하는데 이때 데이터베이스에 이미 있는지 검사하고 저장하는건지? JwtAuthenticationFilter클래스에서 doFilter 메서드에서 저장하는지 그런데 이부분은 저같은 경우에는 GenericFilterBean 을 상속 받았는데 이런 방법을 사용하는 예시 에서는 UsernamePasswordAuthenticationFilter 을 상속받아서 사용하더라구요 지금 막힌 부분이 토큰이 DB에 저장을 어디서 하는지 그리고 아직 토큰유효가 끝나면 리플레시 토큰 요청과 검증후 에세스 재발급 이 남아 있습니다. 어떤 흐름으로 풀어야하는지 알려주세요 ㅠ
개발자
#jwt
#refreshtoken
답변 1
댓글 0
조회 1,291
일 년 전 · 프레드윰 님의 새로운 답변
Spring 과 node.js 두 기술을 동시에
안녕하세요 25살 백엔드가 꿈인 학생입니다:) 처음에는 javascript로 입문하여 node.js 까지 해서 crud는 물론이고 jwt token cookie validation까지 해보았습니다. 알고리즘 문제 중에 세그먼트 트리 까지 javascript로 코드를 작성하고 그 만큼 알아가는 시간도 좀 되어서 그래도 초급은 뗀 정도가 되지않았을까 합니다. 이제는 시장을 고려하여 java를 배워야 하지 않을까 하는 생각에 java를 배우고 알고리즘도 dp 부터 다시 java로 하고 있습니다. 근데 생각보다 재밌어서 다행이었어요. 근데 이제 java spring을 배워야 하는데 뭔가 node를 버리기가 아깝더라고여, 나중에 시장이 어떻게 될지 모르니까요. 근데 또 같이 병행하면 집중이 힘들 거 같고, 또 방치하자니 까먹을 거 같구여… 한국에서 백엔드로서 취업을 하려면 java spring 과 spring boot를 배우는 게 당연한 거겠죠? (가고싶은 기업이 어느쪽인지 정해지지 않았습니다. 근데 스타트업 보다는 중소 이상을 원합니다) 사실 마음은 spring 쪽으로 기울어서 node 의 시장을 볼 때 돌아가지는 않을 거 같긴한데.. 남의 떡이 더 커 보인다고 node가 아쉽네요. 아무리 Java 베이스 node 서브로 하더라도 나중에도 기억해낼 자신이 없어서요..ㅠㅠ Node는 거의 놔주는 게 맞을까요..?
개발자
#node.js
#java
#spring
#node
#backend
답변 1
댓글 0
조회 555
일 년 전 · 민호 님의 새로운 답변
Next.Js (App router) access token 저장위치 및 전달
Next.Js App router로 개발중입니다. fetch를 이용하여 요청을 보내는 로그인기능을 구현하였는데요. 로그인 성공시 서버로부터 내려받는 access token을 어디다 저장하는게 좋을까요? 다른 fetch 요청들의 header에 access token을 전달해주어야 하는데, 이걸 전달하려면 결국 전역저장하는 방법밖에 없지 않나요? axios를 사용하면 defaults.header로 해결할 수 있지만 Next.Js에서 fetch를 지향한다고 들어서 방법을 알고 싶습니다. ㅠㅠ server action을 사용하는 요청들도 있어서 localStorage같은 저장소에 저장하면 접근조차 안됩니다.
개발자
#next.js
#app-router
#jwt
#access-token
#저장
답변 2
댓글 4
추천해요 1
조회 2,193
일 년 전 · 김하림 님의 답변 업데이트
Refresh Token이 만료된다면, 재발급 VS 재로그인 ?
Refresh Token의 만료기한이 Access Token보다 더 길게 설정하였고, 만약 Refresh Token이 만료된다면 Refresh Token을 재발급하는 것이 맞는지 아니면 재로그인을 하도록 에러처리를 하는 것이 맞는지 궁금합니다..
개발자
#백엔드
답변 5
댓글 0
추천해요 1
조회 479