묻고 답해요
160만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[리뉴얼] 맛집 지도앱 만들기 (React Native & NestJS)
메일 남겼는데 ㅠㅠ 읽지 않으셔셔 결제하고남깁니다.
마커찍을때 위경도 가져오는걸로 알고있는데, 그때 지올로케이션 사용했엇거든요 라이브러리 근데 화면 내려갈때나 다른앱 사용할떄 백그라운드 환경으로 변하잖아요 근데 내가 그떄동안 걷고있으면 걷고있던길을 색으로 칠하고 싶다면 백그라운드에서도 해당 위도 경도를 받아와야하는데 즉 백그라인드에서 데이터 받을수있는 부분 강의에있나요 ?
-
해결됨[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
리프레쉬로 리프레쉬 토큰 재발급 상황
안녕하세요 간단한 질문 하나 하겠습니다.단순하게 궁금증이 생겨서요엑세스토큰이 만료되었을때 서버에서 401을 반환하고클라이언트에서는 코드가 401일때 리프레쉬토큰으로 엑세스토큰을 재발급 받고 다시 요청을 보낸다 까지는 이해가 가는데,리프레쉬로 리프레쉬토큰을 발급받는 것은 어떤상황에 사용하는지 감이 안잡혀서 질문드립니다.
-
해결됨[리뉴얼] 맛집 지도앱 만들기 (React Native & NestJS)
로그아웃 관련해서 질문 있습니다.
import {useEffect} from 'react'; import {useMutation, useQuery} from '@tanstack/react-query'; import {queryClient} from 'containers/TanstackQueryContainer.tsx'; import {getAccessToken, logout, postLogin, postSignup, socialLogin} from 'apis'; import {UseMutationCustomOptions} from 'types/mutations/common.ts'; import { numbers, removeEncryptStorage, removeHeader, setEncryptStorage, setHeader, } from 'utils'; import {queryKeys, storageKeys} from 'constants/storageKeys/keys.ts'; function useSignup(mutationOptions?: UseMutationCustomOptions) { return useMutation({ mutationFn: postSignup, throwOnError: error => Number(error.response?.status) >= 500, ...mutationOptions, }); } function useLogin(mutationOptions?: UseMutationCustomOptions) { return useMutation({ mutationFn: postLogin, onSuccess: data => { // 토큰 저장. const accessToken = data.result.accessToken; const refreshToken = data.result.refreshToken; setEncryptStorage(storageKeys.ACCESS_TOKEN, accessToken); setEncryptStorage(storageKeys.REFRESH_TOKEN, refreshToken); setHeader('Authorization', accessToken); }, onSettled: () => { queryClient.refetchQueries({ queryKey: [queryKeys.AUTH, queryKeys.GET_ACCESS_TOKEN], }); }, throwOnError: error => Number(error.response?.status) >= 500, ...mutationOptions, }); } function useSocialIdTokenLogin(mutationOptions?: UseMutationCustomOptions) { return useMutation({ mutationFn: socialLogin, onSuccess: ({result}) => { setHeader('Authorization', result.accessToken); setEncryptStorage(storageKeys.REFRESH_TOKEN, result.refreshToken); }, onSettled: () => { queryClient.refetchQueries({ queryKey: [queryKeys.AUTH, queryKeys.GET_ACCESS_TOKEN], }); }, throwOnError: error => Number(error.response?.status) >= 500, ...mutationOptions, }); } function useGetRefreshToken() { const {data, error, isSuccess, isError, isPending} = useQuery({ queryKey: [queryKeys.AUTH, queryKeys.GET_ACCESS_TOKEN], queryFn: getAccessToken, staleTime: numbers.ACCESS_TOKEN_REFRESH_TIME, refetchInterval: numbers.ACCESS_TOKEN_REFRESH_TIME, refetchOnReconnect: true, refetchIntervalInBackground: true, }); useEffect(() => { if (isSuccess) { setHeader('Authorization', `Bearer ${data?.result.accessToken}`); setEncryptStorage(storageKeys.ACCESS_TOKEN, data.result.accessToken); setEncryptStorage(storageKeys.REFRESH_TOKEN, data.result.refreshToken); console.log(isSuccess, '성공'); } }, [isSuccess]); useEffect(() => { if (isError) { removeHeader('Authorization'); removeEncryptStorage(storageKeys.REFRESH_TOKEN); } }, [isError]); return {isSuccess, isError, error, data, isPending}; } function useLogout(mutationOptions?: UseMutationCustomOptions) { return useMutation({ mutationFn: logout, onSuccess: () => { removeHeader('Authorization'); removeEncryptStorage(storageKeys.REFRESH_TOKEN); queryClient.resetQueries({queryKey: [queryKeys.AUTH, 'getAccessToken']}); queryClient.clear(); }, throwOnError: error => Number(error.response?.status) >= 500, ...mutationOptions, }); } function useAuth() { const signUpMutation = useSignup(); const loginMutation = useLogin(); const socialIdTokenMutation = useSocialIdTokenLogin(); const getNewAccessToken = useGetRefreshToken(); const logoutMutation = useLogout(); const isLogin = getNewAccessToken.isSuccess; const isLoginLoading = getNewAccessToken.isPending; return { signUpMutation, loginMutation, socialIdTokenMutation, isLogin, logoutMutation, isLoginLoading, getNewAccessToken, }; } export default useAuth; // RootNavigator.tsx import FeedTabNavigator from '../tab/FeedTabNavigator.tsx'; import AuthStackNavigator from '../stack/AuthStackNavigator.tsx'; import {useEffect} from 'react'; import SplashScreen from 'react-native-splash-screen'; import useAuth from '../../hooks/queries/AuthScreen/useAuth.ts'; export default function RootNavigator() { const {isLogin, getNewAccessToken} = useAuth(); console.log(isLogin); useEffect(() => { setTimeout(() => { SplashScreen.hide(); }, 1000); }, []); return <>{isLogin ? <FeedTabNavigator /> : <AuthStackNavigator />}</>; } 안녕하세요, 강사님, 강사님 강의를 전체 모두 듣고, 비슷한 느낌으로 풀스택으로 앱개발을 진행하고있습니다.강사님 강의처럼 쿼리를 활용하여 로그인 기능을 구현하고 싶어 useLogout훅에 onSettled를 넣었을 때는 강사님처럼 동일한 이상증상이 발생했고, 이를 해결하기 위해 강사님께서는onSuccess부분에queryClient.resetQueries({queryKey: [queryKeys.AUTH]});이 부분을 넣어주셔서 해결을하셨는데, 저는 해당 부분을 넣어도, 로그아웃이 되었다가, 바로 refreshToken으로 accessToken을 재발급받아, 로그인이 되지 않는 현상이 일어나고있습니다. clear()나 이런 것들을 활용했지만, 제대로 로그아웃이 동작하지 않아. 어떻게 해결할 수 있을지 의견을 구하고자 질문을 남깁니다.
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
CORS 질문 있습니다.
안녕하세요.CORS 에러를 해결하고 있는데, 잘 이해가 가지 않는게 있어서 질문 드립니다.CORS 문제를 해결하기 위해서 이런식으로 Nginx에서 헤더를 달아 줄 수 있도록 설정해뒀습니다.그런데 PATCH, DELETE 요청에서 CORS 에러가 발생합니다. GET, POST 요청은 정상적으로 잘 가는데 말이죠Access to XMLHttpRequest at '[요청 URL]' from origin '[도메인 원본]' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.이렇게 콘솔에 찍히는데, Access-Control-Allow-Credentials 헤더가 안달려서 발생한다는 내용이길래, PATCH, DELETE 메소드일 경우에는 필요한 헤더를 달아 줄 수 있도록 수정해서 설정을 바꿔보면 이번엔 Access-Control-Allow-Origin 헤더가 누락되는 등 문제가 발생하고 있습니다.-- 일반 -- Request URL: [요청 URL] Request Method: PATCH Status Code: 403 Forbidden Referrer Policy: strict-origin-when-cross-origin --응답헤더-- Access-Control-Allow-Origin: [도메인 원본] Cf-Cache-Status: DYNAMIC Cf-Ray: Content-Encoding: br Content-Type: text/html Date: Server: 분명 잘 되던게 갑자기 이렇게 문제가 발생하는것도 이상한데, 같은 서버 설정, 같은 코드로 배포하고 있는 다른 서버에서는 정상적으로 모든 요청이 잘 이루어지고 있습니다.대체 어디를 확인해야 할지 모르겠습니다...
-
미해결Slack 클론 코딩[백엔드 with NestJS + TypeORM]
쿠키 옵션에 대해서 질문 있습니다.
안녕하세요. 백엔드 서버와 클라이언트가 사용하는 도메인이 달라서, 쿠키의 samesite 옵션을 none으로 주고, secure 옵션을 true로 설정해서 사용하고 있습니다. 클라이언트와 서버가 쿠키를 잘 주고받고 있는 것으로 보이는데, 문득 현업에서는 어떻게 옵션을 설정해서 사용하는지 궁금해져서 게시글 남기게 되었습니다. 현업에서는 혹시 도메인이 다른 경우 쿠키 옵션을 어떻게 설정해서 사용하나요?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
nest new nestjs_server 에러
nest new nestjs_server 를 cmd 또는 파워쉘에서 실행하면 아래와같이 나옵니다..yarn 을 잘 선택했구요!애초에 똑같이 하는데 에러가 너무 많이 나와서 nodejs 를 지금 영상에서 나오는 버전으로 검색해서 다운받고 진행했는데 여기서만 딱 에러가 나옵니다.. 구글링도 다 해봐도 안되네요 ㅠㅠFailed to execute command: yarn install --silent× Installation in progress... ☕🙀 Packages installation failed!In case you don't see any errors above, consider manually running the failed command yarn install to see more details on why it errored out.Failed to execute command: git initGit repository has not been initialized
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
guard에서 요청객체 불러오기
bearerTokenGuadr와 basicTokenGuard를 작성했는데, 토큰 추출을 못합니다.에서 req 요청객체를 제대로 불러온 것인걸까요? 포스트맨에서 auth/token/refresh에서 authroization을 체크하거나 체크하지 않건 둘다 토큰이 없다고 나오는데.. 추출에 문제가 있어 보입니다. BasicTokenGuard는 잘 추출되서 로그인까지는 잘 되는데, BearerTokenGuard는 추출이 안되는지 에러메세지 '토큰이 없습니다.'가 나옵니다.
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
Paginate에서 overrideFindOptions 문제
overrideFindOptions에서 where절을 작성하면 dto에 있는 where 조건들이 제대로 동작하지 않는 거 같아요 paginateComments(dto: PaginateCommentsDto, articleId: number) { return this.commonService.paginate( dto, this.commentsRepository, { relations: { author: true, }, select: { author: { id: true, devName: true }, }, where: { article: { id: articleId }, }, }, `articles/${articleId}/comments`, ); }paginate에서 where조건이 있으면 병합하는 방법으로 해결해보려고 했는데 원하는대로 동작하지 않는거 같습니다. 어떻게 해결하면 좋을까요??
-
해결됨[리뉴얼] 맛집 지도앱 만들기 (React Native & NestJS)
BundleIdentifier관련 질문이있습니다.
강사님, 최근에 강사님 강의를 듣고, 실제 프로젝트를 진행하면서 앱 배포 관련해서 이런저런 공부를 하고 있는데 궁금한 점이 생겨 질문드립니다.XCode 에서 BundleIdentifier을 com.xxx.xxxx 이런식으로 제공해주고 있는데. 해당 부분을 URL Scheme으로 활용하여 네이버 로그인을 개발 중에 있습니다. 이 부분을, 그럼@implementation AppDelegate - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { if([RNKakaoLogins isKakaoTalkLoginUrl:url]) { return [RNKakaoLogins handleOpenUrl: url]; } if ([url.scheme isEqualToString:@"{{ CUSTOM URL SCHEME }}"]) { return [[NaverThirdPartyLoginConnection getSharedInstance] application:app openURL:url options:options]; } return NO; } CUSTOM URL SCHEME을 BundleIdentifier로 사용해도 괜찮은지 여부와, 해당 값을 환경변수 처리 없이, 공개적으로 적용해도 되는지 아래와 같이 입니다. if ([url.scheme isEqualToString:@"com.matzip"]) { return [[NaverThirdPartyLoginConnection getSharedInstance] application:app openURL:url options:options]; } return NO; } 혹시 만약에 되지 않는다면 AppDelegate.mm에서 환경변수를 처리하는 방법과, 소셜 로그인시 필요한 URL Scheme은 보통 현업에서 어떠한 식으로 선정하여 처리하는지 궁금하여 질문드립니다.
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
임시 폴더로부터 이미지 파일 이동시키기
임시폴더로 부터 이미지 파일 이동시키는 강의를 들었는데요.지금은 아직 S3 를 사용하지 않지만 만약 S3 를 사용할때도 임시폴더를 만들어두시고, 최종적으로 저장을하게 되면 이미지 파일을 S3에 이동을 시키시나요 ?
-
해결됨[리뉴얼] 맛집 지도앱 만들기 (React Native & NestJS)
폰트 관련 궁금사항입니다.
안녕하세요, 강사님, 강사님 강의를 들으며, 개인적인 프로젝트를 RN으로 진행중에 비슷한 상황이 발생하여 질문을 남겨봅니다.아이콘같은 경우도, 이전에 잘 동작하다가 빌드 후, 에러가 발생하면 빌드 페이즈에 추가로 파일을 넣어서 해결하였습니다.이번에 제가 추가한 폰트도, 이전에 잘 동작하다가, 해당 브랜치를 develop에 머지한 후, 새로 다른 브랜치를 만들어 작업중인데, 이전에 잘 동작했지만 동작하지 않습니다.빌드 페이즈에 들어가있는걸 확인했는데 잘 동작하지 않는 경우는 어떻게 해결할지 의견을 구하고자 질문을 남깁니다.
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
file upload common module 관리
강의에서 image 업로드 시에common module 를 만들어서 업로드 진행하는것을 봤는데요.controller 단에서 타고와서 메서드에서 필터링 처리하는게 아니라,이미 module 에서 검증된것을 파일 올리기만 하니까 간편해보였습니다.만약 이미지 파일뿐만 아니라 , 엑셀파일로 업로드 받는다고 하면 어떻게하면될까요 ??그때도 common.modules.ts 파일안에 register 메서드에 조건문으로 처리하시나요 ??ex) if (ext === '.xlsx') { } elif (ext === '.jpg' && ext === '.jpeg' && ext === '.png') { }
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
이미지 업로드
안녕하세요 ㅎ이미지 업로드 방식에 대해서 말씀해주셨는데요.말씀하신것처럼 사용자가 이미지를 올렸다가 마음이 바껴서 다른 이미지를 올리고싶을때 다시 이미지를 여러번 교체할수있잖아요하지만 데이터베이스 상에서는 마지막으로 올린 S3 경로가 저장되어있을텐데요.이럴경우 데이터베이스상에는 저장이 되어있지않지만 S3 에 올라간 이미지들은 어떻게 하시나요 ?주기적으로 삭제 해주신다고 하셨는데 어떤방식을 하시나요 ?
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
이미지 저장 경로 Public
안녕하세요 ! 우선 지금은 공부 단계이기때문에 이미지저장 경로를 S3 로 하지않고 Public 으로 하시나요 ?아니면 원래 Public 에다가 이미지를 저장하시나요 ??
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
...
..
-
해결됨[리뉴얼] 맛집 지도앱 만들기 (React Native & NestJS)
애플 로그인 관련 궁금한 부분.
안녕하세요, 강사님 강의처럼 Signing & Capabilites부분에서 +버튼을 누르면 Signinwith apple 부분이 보이지 않습니다. 이 부분은 어떻게 해결해야하나요?
-
해결됨[리뉴얼] 맛집 지도앱 만들기 (React Native & NestJS)
안드로이드 시뮬레이터
❗질문 작성시 꼭 참고해주세요최대한 상세히 현재 문제(또는 에러)와 코드(또는 github)를 첨부해주셔야 그만큼 자세히 답변드릴 수 있습니다.맥/윈도우, 안드로이드/iOS, 버전 등의 개발환경도 함께 적어주시면 도움이 됩니다. 에러메세지는 일부분이 아닌 전체 상황을 올려주세요!안녕하세요.vs code 터미널에서 안드로이드 시뮬레이터를 켜기위해$ npx react-native run-android를 실행하면 error Failed to install the app. Make sure you have an Android emulator running or a device connected.디바이스가 연결되어있는지 확인하라고 뜨고 Android Studio 를 켜서 virtual deivce manager 에서 디바이스를 연결해놓고 하면 잘되는데 원래 Android Studio에서 디바이스를 연결해놓고 $ npx react-native run-android 를 실행하는게 맞는건가해서요.
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
수업 외적질문...
이건 수업 외적인 질문인데요. 목소리가 달라서 다른 강사님이시지만.. 똑같은 코드팩토리 Flutter 수업듣고있는데요TypeScript 와 Nest js 를 사용하시면 React Native 를 학습하시고사용하시는게 나을수도 있을텐데 , Flutter 를 선택하신 이유가 있나요 ??React Native 가 성능이 비교적 Flutter 보단 안좋다고 하지만 큰 기업들에선 React Native 도 많이 사용하고 있던데 그럼 쓰는사람에 따라 다른게 아닐까?? 생각도 했거든요
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
로그인/소셜로그인 테이블 설계 관련 궁금증 관련 질문입니다.
강좌를 들은 후, 소셜로그인을 구현하다가 의문점이 생긴 부분이 있어 어떠한 방식으로 접근하는 것이 궁금하여 질문을 남깁니다.상황일반 회원가입시에는, 이메일 비밀번호 + 해당 서비스에 필요한 필수 정보들을 받고, 해당 내용을 클라이언트로 부터 받아 user테이블에 저장하는 상황입니다.소셜 로그인 같은 경우에는, 정보를 받을 수 있는 것이 제한이 되어있어, 추가적으로 필요한 정보들을, 소셜 로그인 성공 이후, 클라이언트 측에서 회원가입시 필요한 정보들을 받을 수 있는 화면으로 이동시켜, 해당 정보를 받아서, 부족한 정보들을 채워넣는 것으로 알고 있습니다.궁금점.소셜로그인 로그인 후, 신규 유저이기에 서비스 이용에 필요한 필수 부가정보 입력을 받기위해, 회원가입 창으로 이동시켜, 부가 정보를 입력받는다면 크게 문제가 없습니다.하지만, 앱을 사용하다보면은 데이터가 끊긴다거나, 배터리가 방전된다거나, 알수없는 이유로, 로그인은 되었으나, 필수 부가정보를 입력하지 못하고, 꺼지는 경우가 있습니다. 필수 부가정보를 꼭 받아야 하는 경우라면 이 부분에 대해서 어떻게 처리해야하나요?필수 정보를 채웠는지 여부를 확인하는 column을 boolean으로 User 테이블에 추가하여, 클라이언트에서 해당 Column으로 부가정보를 입력받지 않았으면 메인화면으로 가지않고, 회원가입 스크린으로 리다이렉 시키는 이런 로직을 작성해야하나요?필수 정보를 채웠는지 여부를 확인하는 column 없이 이런 경우에 처리할 수 있는 방안이 있는지 궁금하고, 현업에서는 어떤식으로 테이블을 설계하는지 궁금합니다!
-
미해결[코드팩토리] [초급] NestJS REST API 백엔드 완전 정복 마스터 클래스 - NestJS Core
overridFindOptions
안녕하세요 코팩님! 개인 프로젝트를 하다가 약간의 오점을 발견해서 질문드립니다.위 사진과 같이 paginate함수의 overrideOptions 파라미터에 where필터를 새로 작성하는 순간,기존에 composeOptions에서 작성한 where필터를 아예 무시해버리게 되는 것 같습니다. 그래서 첫 번째 페이지는 정상적으로 응답이 오는데, next에 담긴 링크를 눌러보면 똑같이 첫번째 페이지가 응답으로 오게되는 것 같아요.위와같은 증상이 뒷부분의 paginateComments에서도 똑같이 발생합니다. 첫번째 페이지는 작동이 잘 되기때문에 영상에서는 넘어가신 듯 한데,여러 방법을 써봤지만 해결책이 보이지 않아서 질문드립니다ㅠ