묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결
인프런 강사 관련 문의
안녕하세요 강사 등록 관련한 문의 사항이 있습니다. 인프런 강사로 등록할 경우운영하는 강의에 대한 수강생의 ID정보나, 어느 수업에 언제 등록했는지같은 정보를 받을 수 있는지 궁금합니다. 자세하게 답변 해주시면 감사하겠습니다.고객센터 번호도 알려주시면 감사하겠습니다.
-
미해결[개정판 2023-11-27] Spring Boot 3.x 를 이용한 RESTful Web Services 개발
모든 섹션 강의자료
안녕하세요. 이번에 새로 수강할려고 하는데 혹시 모든 섹션 강의자료는 어디서 다운받을 수 있을까요?
-
해결됨하루만에 배우는 AWS REDIS
세션3 마지막 퍼블릭 아이피 할당이 안됄때
다음과 같은 양식으로 남겨주세요.질문을 한 배경 : 강의대로 따라했을때 에러가떳음질문내용 : 해결방법 - https://programforlife.tistory.com/8그런데 보안상 좋을지 모르겠음게이트웨이 에니웨어설정한시점에서도 보안상좋은지모르겠음
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
Section 50 퀴즈 관련 질문입니다.
backend playground를 보고 작업하고 있으나 추가로 질문 드려야만 해결할 수 있는 부분이 있어 여쭤봅니다.loading 페이지에서 createPointTransactionOfLoading을 사용하여 이것을 complete 페이지에서 fetch해서 가져와야할 거 같은데 fetch 할 때 필요한 api를 모르겠어서 임시로 fetchPointTransactionsOfSelling로 했습니다. createPointTransactionOfLoading 부분에서 id는 사용자 아이디인데 impUid는 뭘 의미하나요? 회원가입 하면 id가 발급되는 것처럼 해당 api에서 자체적으로 발급되는 걸까요?amount가 포인트 양인 것 같아서 기존의 포인트에 포인트를 중첩하려면 loading과 complete에 동일한 api를 fetch해서 Selected를 더하는 게 맞나요?createPoint와 fetchPoint할 때 필요한 요소는 뭐가 더 있는지 궁금합니다.complete 페이지에서 'IPointTransaction[]' 형식에 'amount' 속성이 없습니다. 라고 뜨는데 어떻게 해결하나요? 작성한 코드입니다.complete ({data?.fetchPointTransactionsOfSelling.amount}에 amount 속성이 없다는 빨간 줄) import { gql, useQuery } from "@apollo/client" import type { IQuery, IQueryFetchPointTransactionsOfSellingArgs } from "../../../../src/commons/types/generated/types" const FETCH_POINT = gql` query { fetchPointTransactionsOfSelling { _id impUid amount } } ` export default function CompletePage():JSX.Element { const { data } = useQuery<Pick<IQuery,"fetchPointTransactionsOfSelling">,IQueryFetchPointTransactionsOfSellingArgs>(FETCH_POINT) return <>충전한 포인트는 {data?.fetchPointTransactionsOfSelling.amount}원</> }loading (Number(amount)에 이름 찾을 수 없다는 빨간 줄)import { gql, useQuery, useMutation } from "@apollo/client" import type { IQuery } from "../../../../src/commons/types/generated/types" import { loginCheck } from "../../../../src/components/commons/hocs/withAuth" import { useRouter } from "next/router" import type { ChangeEvent } from "react" import { useState } from "react" const FETCH_USER_LOGGED_IN = gql` query { fetchUserLoggedIn { email name } } ` const CREATE_POINT = gql` mutation createPointTransactionOfLoading($impUid:ID!){ createPointTransactionOfLoading(impUid:$impUid){ _id impUid amount } } ` declare const window: typeof globalThis & { IMP: any } function LoadingPage():JSX.Element { const router = useRouter() const { data } = useQuery<Pick<IQuery,"fetchUserLoggedIn">>(FETCH_USER_LOGGED_IN) const [ myFunction ] = useMutation(CREATE_POINT) const selectList = [0,500,1000,2000,5000]; const [Selected, setSelected] = useState(0); const handleSelect = (e:ChangeEvent<HTMLSelectElement>):void => {setSelected(Number(e.target.value));}; const onClickPayment = ():void => { if (Selected === 0) { alert("금액을 선택해주세요."); return; } const IMP = window.IMP; IMP.init("imp27255777"); IMP.request_pay({ // param pg: "kakaopay", pay_method: "card", // merchant_uid: "ORD20180131-0000011", name: `Section 50-${Selected}원 결제`, amount: Selected, buyer_email: data?.fetchUserLoggedIn.email, buyer_name: data?.fetchUserLoggedIn.name, buyer_tel: "", buyer_addr: "", buyer_postcode: "", m_redirect_url:"" }, async (rsp:any) => { if (rsp.success === true) { await myFunction({ variables:{ impUid : data?.fetchUserLoggedIn._id, amount: Number(amount) + Selected } }) const {Modal} = await import("antd") Modal.success({content:"등록 성공"}) void router.push("/z_quiz/section50/complete") } else { alert("결제 실패") } }); } return (<> <div>{data?.fetchUserLoggedIn.name}님 환영합니다.</div> <select onChange={handleSelect} value={Selected}> {selectList.map((item) => ( <option value={item} key={item}>{item}</option> ))} </select> <script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js" /> <script src="https://cdn.iamport.kr/v1/iamport.js" /> <button onClick={onClickPayment}>충전하기</button> </>) } export default loginCheck(LoadingPage);loginimport { gql, useMutation } from "@apollo/client" import { type ChangeEvent, useState } from "react" import type { IMutation, IMutationLoginUserArgs } from "../../../../src/commons/types/generated/types" import { useRecoilState } from "recoil" import { accessTokenState } from "../../../../src/commons/stores" import { useRouter } from "next/router" import { wrapFormAsync } from "../../../../src/commons/libraries/asyncFunc" const LOGIN_USER =gql` mutation loginUser($email:String!, $password:String!){ loginUser(email:$email,password:$password){ accessToken } } ` export default function LoginPage():JSX.Element { const router = useRouter() const [email, setEmail] = useState('') const [password, setPassword] = useState('') const [loginUser] = useMutation<Pick<IMutation,"loginUser">,IMutationLoginUserArgs>(LOGIN_USER) const [, setAccessToken] = useRecoilState(accessTokenState) const onChangeEmail = (event: ChangeEvent<HTMLInputElement>):void => { setEmail(event.currentTarget.value) } const onChangePassword = (event: ChangeEvent<HTMLInputElement>):void => { setPassword(event.currentTarget.value) } const onClickLogin = async ():Promise<void> => { try { const result = await loginUser({variables: { email, password }}) const accessToken = result.data?.loginUser.accessToken if (accessToken=== undefined) { alert("로그인 실패") return ;} setAccessToken(accessToken) localStorage.setItem("accessToken", accessToken) void router.push("/z_quiz/section50/loading") } catch(error) { if (error instanceof Error ) alert(error.message) } } return ( <form onSubmit={wrapFormAsync(onClickLogin)}> 이메일: <input type="text" onChange={onChangeEmail} /> 비밀번호: <input type="password" onChange={onChangePassword} /> <button>로그인</button> </form> ) }
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Validator
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]1. V3dp ItemValidator 클래스를 적용하는 코드가 보이지 않는데 적용되는 이유가 궁금합니다.Validation이 데이터의 유효성을 검사하는 걸로 알고 있습니다. @ModealAttribute에서 타입 변화가 되지 않는 것들에 대해 ValidationBean이 적용되어야 하는 것이 아닌가요? 왜 타입 변화가 실패한 것에 대해서 ValidationBean 적용을 하지 않는지 궁금합니다. 제가 반대로 이해하고 있는 것 같은데 무엇을 잘못 이해하고 있는지 궁금합니다.
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 백엔드 코스
grpahql-upload이슈
안녕하세요 원두멘토님! 13챕터에서 graphql-upload 버전이슈로 버전을 낮춰 대응하셔 작동이 되게 알려주셨습니다.확인을 해보니 apollo server에서 원래 패키지에 포함시켰던 디펜젼시를 csrf문제로 포함시키지 않고 분리를 해서 버전관리가 되지 않아서 생긴 문제인것 같았습니다.제가 궁금한 점은 graphql-upload로 클라이언트에게 업로드 기능을 제공해주는 것이 아닌 다른 방법으로 grpahql에서 upload기능을 제공해 줄수있는지 궁금합니다.보안상 좋지 않고 버전관리가 되지 않는 패키지는 사용하는것이 나중을 생각했을때 더 개발난이도가 올라갈 것 같다 생각이 들었습니다.제가 생각한 방법은 multer를 사용하는 건데 그렇게 하려면 restapi로 제공을 해줘야 하는데 grpahql 과 restapi를 같이 사용해서 api를 제공해줘야하는데 이 또한 가능하거나 추천하시는지 궁금합니다.
-
해결됨[게임 프로그래머 도약반] DirectX11 입문
Transformation pipeline 질문
제가 원래는 wvp matrix로 곱해서 주어진 값을 w에있는 z값으로 나누어서 x,y는 -1~1z는 0~1로 클립핑 하고 래스터라이즈로 들어간다고 생각했었는데 이번 강의를 수강하면서 ms문서나 블로그들을 조사해보니까클립핑할때는 x,yz 를 w랑 직접비교하고 그이후에 viewport로 변환을 미리 해주고 마지막에 w값을 나누어 주더라구요 먼저 제가 잘 이해했는지 궁금하고 그리고 viewport좌표로 변환하는 매트릭스는 Context->rssetviewport하는 과정에서 내부적으로 만들어지는건가요?그리고 rasterizer 로 주어지는 값은 (800,600)을 예로 했을때 (0~800,0~600,0~1,1)이렇게 되나요?감사합니다!!
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
추가 질문
https://www.inflearn.com/questions/961239/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8%EB%A5%BC-%EB%A7%88%EC%B9%98%EB%A9%B0-%EB%B0%B0%ED%8F%AC-%ED%8E%98%EC%9D%B4%EC%A7%80%EC%97%90%EC%84%9C-%EC%97%85%EB%A1%9C%EB%93%9C-%EC%9E%91%EB%8F%99%EC%9D%B4-%EC%95%88%EB%90%A8"프로젝트를 마치며 배포 페이지에서 업로드 작동이 안됨"이라는 제목의 질문글의 추가 질문입니다.=====================이전 질문 내용==========================================상품 업로드에 관한 이슈과정을 다 마치고, fly.io와 vercel.com을 통하여 배포한 페이지 중에서 상품 업로드가 제대로 이뤄지지 않습니다.github 주소 :https://github.com/arominddo/Inflearn_full_stack_boot_campvercel을 통해 배포된 web 어플리케이션 url :https://grab-market-client-ashen.vercel.app/ grab_market_web > src > upload > index.js에 코드 내용이 작성되어 있습니다. 배포된 페이지의 DB 초기화 문제프로젝트를 전부 마치면서, 다시 한번 fly.io에 최신 코드로 재배포를 해보고 실험을 해보았는데도, web에서 특정 상품을 업로드하거나(오류가 나지 않았을 당시), 상품 구매하기 기능을 통하여 soldout 값을 1로 바꿔줬음에도,약 5분이 지나면 DB가 배포 됐을 당시의 내용으로 계속 초기화가 됩니다.해결 방안이 궁금합니다.ex) A라는 물건 업로드 -> 5분 지남 -> 새로고침 해보면 A라는 물건이 리스트에서 삭제ex) B라는 물건 구매 하기 버튼 클릭 -> soldout 값 1로 변경 -> 약 5분 지남 -> 다시 soldout 값 0으로 복귀=================================================================================== 위와 같은 이전 질문 내용에서 1번에 해당하는 답변으로, 어떤 오류 로그가 뜨냐고 물어보셔서 여기 다시 남겨봅니다. 위 사진은 vercel을 통해 배포 된 Web에서 upload를 시도하면 나오는 오류 로그입니다. upload 시도 시에 fly.io 모니터화면에서 볼 수 있는 오류입니다.참고로, Local 환경에서 같은 코드로 npm start로 실행된 서버와 web에서는 업로드 기능이 잘 작동됩니다. 재부팅에 관련된 로그라고 생각되는 부분 캡쳐해서 보내드립니다. 이와 같은 로그가 뜨면서 배포된 서버의 내용이 배포 시점으로 돌아가는 것 같습니다.그런데 로그를 보자면 reboot라는 것이 단순히 서버를 죽였다가 다시 올리는 것으로 생각 되는데, 배포된 서버가 돌아감에 있어서 업로드 되거나 값이 변했던 내용들이 다 사라지는 것이 이해가 되지 않습니다ㅠㅠ
-
미해결[코드팩토리] [중급] Flutter 진짜 실전! 상태관리, 캐시관리, Code Generation, GoRouter, 인증로직 등 중수가 되기 위한 필수 스킬들!
페이지 fetchMore 중복요청 문제
섹션 9 상태관리 프로젝트에 적용하기 > 완성된 Pagination 로직 실행해보기8분경에 요청이 중복으로 들어가는 부분을 고친다고 말씀하셨는데저부분을 고치는 강의가 뒤에 있나요?다른 프로젝트에 적용할때 같은 문제가 발생해서언급을 하셨다면 어느부분인지 찾지를 못하겠네요.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
1:1맵핑에서 주인이 아닌 객체의 set함수를 처리할 방법이 없을까요?
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]예를들어Locker와 Member가있다고 하면Member가 주인이라고 했을때 Member에서 연관관계메소드로 settingLocker(Locker locker)이 있다고 하면 해당 함수 내용이this. Locker = locker;locker.setMember(this);가 되는 거잖아요?하지만 저는 mappedby 로 되어있는 Locker에서 set을 해봤자 실제 Db에는 적용되지 않기때문에 다른 개발자가 실수로라도 locker.setMember()함수를 사용하지 못하게 하고싶은데 이런경우에는 어떻게 해야하는지 알 수 있을까요?
-
해결됨Java TPC (생각하고, 표현하고, 코딩하고)
call by reference 관련 자바는 call by value방식만 존재하지 않나요?
엄밀하게 따지면 JAVA는 모두 call by value로 알고 있습니다.call by reference 방식은 실제 메모리의 주소값을 전달하여 원본 자체의 주소가 바뀌는 방식으로 알고있습니다.반면 자바에서 reference type을 메서드로 전달하여 값이 바뀌는건, 메서드내에서 reference type 의 주소를 복사받아. 주소의 변화 없이 값만 조정하는걸로 압니다.즉 메서드 내에서 전달받은 복사된 주소값으로, 해당 객체나 배열의 값을 수정하는거지. 원본 자체의 변화는 없는걸로 학습했는데, 제가 학습한게 맞을까요?
-
미해결Practical Testing: 실용적인 테스트 가이드
외부 세계에 영향을 주는 코드
관측할 때마다 다른 값의 의존하는 코드는즉, 현재시각, 랜덤 값 등등은 이해 하겠는데외부 세계에 영향을 주는 코드는 어떤 건지 이해가 잘 안되서요.혹시 간단한 예제를 들어주실수 있으실까요?
-
해결됨14일만에 배우는 ASP.NET CORE
ADO.NET 엔터티 데이터 모델이 없어요
.net core 3.1 버전이고 VS2022 사용하고 있습니다. New item 항목에 ado.net 엔터티 데이터 모델 플랫폼이 없네요.installer에서 EF 6 도구와 .NET Framework 프로젝트 및 항목 템플릿 둘 다 체크되어 있습니다.
-
미해결파이썬 알고리즘 문제풀이 입문(코딩테스트 대비)
K번째 수
안녕하세요초보여서.. 아무리 봐도 이해가 안가서 문의 드립니다. T,T기초적인 질문이라도 이해 부탁드립니다. T = int(input()) 의 값이 왜 input 파일의 첫번째 값이 나오는지 이해가 안갑니다. for 문에서 2번을 수행하는데 첫번째 수행에서 n,s,e,k 에는 INPUT 파일의 2번째 줄의 값이 들어가고, a에는 INPUT DML 3번째 줄의 값이 들어가는지 이해가 안갑니다. (마찬가지로 2번째 수행에서는 4,5번째 줄이 들어가는것도 이해가 안갑니다)바쁘시겠지만 답변 부탁드릴께용
-
미해결웹 게임을 만들며 배우는 React
웹팩 설정을 마쳤는데 npx webpack 했을 때 원하는 결과가 안 나옵니다.
WARNING in configuration The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/ ERROR in main Module not found: Error: Can't resolve './src' in 'C:\study\zerocho\lecture' resolve './src' in 'C:\study\zerocho\lecture' using description file: C:\study\zerocho\lecture\package.json (relative path: .) Field 'browser' doesn't contain a valid alias configuration using description file: C:\study\zerocho\lecture\package.json (relative path: ./src) no extension Field 'browser' doesn't contain a valid alias configuration C:\study\zerocho\lecture\src is not a file .js Field 'browser' doesn't contain a valid alias configuration C:\study\zerocho\lecture\src.js doesn't exist .json Field 'browser' doesn't contain a valid alias configuration C:\study\zerocho\lecture\src.json doesn't exist .wasm Field 'browser' doesn't contain a valid alias configuration C:\study\zerocho\lecture\src.wasm doesn't exist as directory existing directory C:\study\zerocho\lecture\src using description file: C:\study\zerocho\lecture\package.json (relative path: ./src) using path: C:\study\zerocho\lecture\src\index using description file: C:\study\zerocho\lecture\package.json (relative path: ./src/index) no extension Field 'browser' doesn't contain a valid alias configuration C:\study\zerocho\lecture\src\index doesn't exist .js Field 'browser' doesn't contain a valid alias configuration C:\study\zerocho\lecture\src\index.js doesn't exist .json Field 'browser' doesn't contain a valid alias configuration C:\study\zerocho\lecture\src\index.json doesn't exist .wasm Field 'browser' doesn't contain a valid alias configuration C:\study\zerocho\lecture\src\index.wasm doesn't exist webpack 5.88.2 compiled with 1 error and 1 warning in 196 ms처음에 위와 같은 에러코드가 나와서 lecture안에 src폴더를 만들고 그안에 index.js, index.json, index.wasm 파일을 직접 생성해주었습니다.그 다음에는 아래와 같은 에러코드가 나오면서 main,js 파일이 생성됐는데 안에는 아무 내용도 없습니다.asset main.js 0 bytes [emitted] [minimized] (name: main) ./src/index.js 1 bytes [built] [code generated] WARNING in configuration The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/ webpack 5.88.2 compiled with 1 warning in 212 ms PS C:\study\zerocho\lecture> npx run Need to install the following packages: run@1.4.0 Ok to proceed? (y) y Found 0 argument(s). Expected one or more. Usage: runjs [SIGNAL] somecode.js [--args] Ex: runjs somecode.js --args runjs SIGUSR2 somecode.js --args그리고 webpack.config.js에 보면 강의에서 했던대로 mode: "development",라고 이미 적용되어있는 상태입니다.
-
미해결[왕초보편] 앱 8개를 만들면서 배우는 안드로이드 코틀린(Android Kotlin)
저도 북마크해둔게 이미지가 안뜹니다
다른건 다 뜨는데 북마크한 이미지가안뜨는데 문제를 모르겠습니다. https://drive.google.com/drive/folders/1KXAgrtBwc66ZlSZUpl2wWSZ3SB8mAG8u?usp=drive_link
-
미해결스프링 시큐리티 OAuth2
소셜 로그인 관련 질문드립니다!!
안녕하세요 강사님, 강의 정말 잘 듣고 혼자 힘으로 최대한 자료 안보면서 머리 싸매면서 구현해보고 있습니다. 강의 후반부 까지 듣다가 잠시 중단하고 긴가민가 한 부분만 찾아서 다시 듣고 있는 상황입니다. 사진은 ChatGPT 로그인 화면이고 구현하고자 하는 목표입니다.다만, Session 을 사용하지 않으려고 합니다. 거기에 많은 분들이 질문하신 소셜 로그인 이후에 토큰을 가지고 서버에 인가를 요청하는 과정을 구현하고자 합니다.그리고 아래는 제가 이렇게 구현하면 되지 않을까? 생각한 내용이고, 한번 시간내서 봐주시면 정말 감사하겠습니다. (질문시작)AuthorizationRequestRepository<OAuth2AuthorizationRequest>강의에서도 나오지만 OAuth 2.0 가 default 로 Authorization Request 를 Session 에 저장합니다. 이를 그대로 사용하지 않고 Cookie 에 저장하기 위해서 다른 블로그를 참고했습니다.@Override public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest request) { return CookieUtil.getCookie(request, OAUTH2_AUTHORIZATION_COOKIE_NAME) .map(cookie -> CookieUtil.deserialize(cookie, OAuth2AuthorizationRequest.class)) .orElse(null); } @Override public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationRequest, HttpServletRequest request, HttpServletResponse response) { if(authorizationRequest == null) { CookieUtil.deleteCookie(request, response, OAUTH2_AUTHORIZATION_COOKIE_NAME); CookieUtil.deleteCookie(request, response, REDIRECT_URI_PARAM_COOKIE_NAME); return; } CookieUtil.addCookie(response, OAUTH2_AUTHORIZATION_COOKIE_NAME, CookieUtil.serialize(authorizationRequest), cookieExpireSeconds); String redirectUrlAfterLogin = request.getParameter(REDIRECT_URI_PARAM_COOKIE_NAME); if (StringUtils.isNotBlank(redirectUrlAfterLogin)) { CookieUtil.addCookie(response, REDIRECT_URI_PARAM_COOKIE_NAME, redirectUrlAfterLogin, cookieExpireSeconds); } } @Override public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) { return this.loadAuthorizationRequest(request); } public void removeAuthorizationRequestCookies(HttpServletRequest request, HttpServletResponse response) { CookieUtil.deleteCookie(request, response, OAUTH2_AUTHORIZATION_COOKIE_NAME); CookieUtil.deleteCookie(request, response, REDIRECT_URI_PARAM_COOKIE_NAME); } 이후 OAuth 2.0 로그인에 성공 이벤트를 처리할 successfulHandler 를 생성합니다.@Component public class OAuth2AuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { // Token 유효성 검사 // Token 생성 // redirect_uri 로 사용자 redirect }여기까지 과정을 간단요약해 보겠습니다.유저가 소셜 로그인 버튼(google, github, kakao) 을 누른다.스프링부트 서버에서 /oauth2/authorization/${provider}?redirect_uri=http://localhost:3000/oauth/redirect 로 인가서버에게 요쳥을 보낸다.인가서버마다 설정된 authorization_code 의 엔드포인트로 redirect 된다.획득한 authorization_code 를 인가서버가 다시 스프링부트 서버로 전송한다.스프링부트 서버에서 다시 authorization_code 를 사용해서 access_token 을 요청한다. 인가서버는 access_token 을 스프링부트 서버로 전송한다. 스프링부트 서버는 access_token 을 이용해서 리소스 서버에 user_info 를 요청한다. 소셜 로그인인 경우, 인가서버와 리소스 서버가 동일하다.스프링부트 서버는 user_info 를 획득한다. 해당 정보를 DB 에 저장한다.그리고 스프링부트 서버에서 access_token 과 refresh_token 을 생성한다.refresh_token 은 수정이 불가능한 cookie 에 저장하고, access_token 은 프론트엔드로 redirect_uri 의 query-string 에 담아서 보낸다. 해당 access_token 은 localStorage 에 저장한다.혹은 refresh_token 은 스프링부트 서버가 가지고 있으며 DB 에 저장하고, access_token 만 cookie 에 담아서 프론트엔드에 보낸다.프론트엔드 서버에서 스프링부트 서버에서 전달받은 토큰을 localStorage 에 저장하고, 다시 스프링부트 서버로 요청을 보낼시 Authorization: Bearer ${access_token} 을 HTTP 헤더에 담아서 보낸다.스프링부트 서버에서 JwtDecoder 를 이용해서 access_token 을 검증한다. 만약 expiration date 가 지났다면 access_token 과 refresh_token 을 모두 재발급한다. (혹은 access_token 만 재발급한다) 출처는 이곳 입니다. (질문1)위의 순서가 합당하다면 강의 내용을 바탕으로 제가 추가적으로 구현할 부분은 스프링부트 서버에서 access_token, refresh_token 을 생성하는 로직(세션을 비활성화하고) 토큰을 cookie 에 담아서 보내는 로직스프링부트 서버에서 access_token 을 검증하고 재발급하는 로직인게 맞는건지 궁금합니다. (질문2)외부 인가서버를 사용하지 않고 OAuth 2.0 Resource Server, Client, Authorization Server 를 사용해서 스프링부트 서버가 모든 인증 & 인가의 책임을 가지게 된다면, 결국 google, github, naver 등의 외부 인가서버를 이용하는 것과 크게 차이가 나지 않는건가요? 어짜피 많은 부분을 OAuth 2.0 라이브러리가 지원해준다면, 외부 인가서버를 도입해서 커플링 시키느니 공공기관 납품하는 경우에는 직접 인가서버, 리소스서버를 구현하는 것이 더 실무에서 자주 일어나는 일인지 궁금합니다.(* 제가 일하던 작은 si 회사에서는 참여했던 프로젝트가 공공기관 프로젝트가 폐쇄망에서만 실행되는 내부 관리자 용이여서 보안 관련된 아주 간단한 설정만을 접해봤습니다.)(그리고 아직 강의 후반부 통합 연동부분을 다 듣지 못했습니다 ㅜ.ㅜ) (질문3)Keycloak, Okta 같은 오픈소스 인가서버를 사용하는 경우 토큰 관리, 세션 관리, 유저 관리 등이 개발자가 뭘 해줄것도 없이 인가서버에서 관리를 해줘서 굉장히 편하다는 것을 이해했습니다. 하지만 검색을 좀 해봐도 관리자가 한땀한땀 인가서버에 등록해주는 것이 아니라 일반적인 사이트에서 처럼 form 요청으로 키클록 서버에 자동으로 User 정보가 등록되는 것이 가능한지 모르겠습니다.보안이 중요한 기관에서 로그인 요청을 보내고, 며칠뒤에 계정이 만들어지는 것이 이런 프로그램을 이용해서인가.. 싶기도 하고 궁금하네요.
-
해결됨[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
구독에관해 질문있습니다.
Managers.Input.MouseAction -=OnMouseClickedManagers.Input.MouseAction +=OnMouseClicked 가 PlayerController안에 있는데 PlayerController가 여러게임 오브젝트에 붙어있을경우 -=OnMouseClicked로 먼저 제거한후 +=OnMouseCliked로 구독하니까 여러 오브젝트중 하나만 움직여야 한다고 생각했는데 그렇지 않아서 질문합니다.MouseAction에는 같은 이름의 OnMouseClicked를 추가하더라도 각 오브젝트마다 각각 다른 OnMouseClicked로 관리되나요?
-
미해결자바(Java) 알고리즘 문제풀이 입문: 코딩테스트 대비
8-1번 합이 같은 부분집합 질문 드립니다.
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; public class Main { static int sum = 0; static int n; static int[] arr; static boolean flag = false; static String answer = "NO"; public static void main(String[] args) throws IOException { Scanner kb = new Scanner(System.in); n=kb.nextInt(); arr = new int[n]; for(int i=0; i<n; i++){ arr[i]=kb.nextInt(); sum+=arr[i]; } DFS(0, 0); System.out.println(answer); } static void DFS(int i, int part_sum){ if(flag == true) return; if(i == n){ if(sum == (sum-part_sum)){ flag = true; answer = "YES"; } } else{ DFS(i+1, part_sum + arr[i]); DFS(i+1, part_sum); } } }위와 같이 코드를 짰습니다.주어진 예제도 잘나오는데 채점사이트에 입력하면 계속 오답이라고 나오네요ㅠㅠ 로직도 똑같은데 뭐가 문제일까요..
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
Send lock 관련 질문
public void Send(byte[] sendBuff) { lock (_lock) { _sendQueue.Enqueue(sendBuff); if (_pendingList.Count == 0) RegisterSend(); } } void OnSendCompleted(object sender, SocketAsyncEventArgs args) { lock (_lock) { if (args.BytesTransferred > 0 && args.SocketError == SocketError.Success) { try { _sendArgs.BufferList = null; _pendingList.Clear(); // Doing if (_sendQueue.Count > 0) RegisterSend(); } catch (Exception e) { Console.WriteLine($"OnSendCompleted Failed {e}"); } } } }수업을 들으면서 Send와 OnSendCompleted에 lock이 서로 다른 두개이상의 쓰레드가 동시에 sendQueue, pendingList에 Write하는 것을 방지하는 것이라고 이해했습니다.그리고 Send의 if문이 다른 쓰레드가 전송중일때를 체크하는 것이라고 들었는데 저 2개의 lock구조에서, 쓰레드A가 OnSendCompleted의 lock구역안에 있을 때 쓰레드B가 Send의 lock구역에 진입이 가능한지 궁금합니다.만약 접근이 안된다면 pendingList.Count가 항상 0이 되지않을까 생각하고 있습니다.