묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
포트폴리오 관련 질문
강의의 중고마켓 포트폴리오를 만들고 있는 수강생입니다해당 포트폴리오는 배포를 못한다고 알고 있는데, 배포링크 없는 프로젝트를 면접관이 안좋게 보지 않을지 걱정됩니다(git소스코드와 함께 readme에 gif, 기타 설명은 첨부하려고 합니다)그래서 다 수강한 후에 강의의 프로젝트와 함께, 배포까지 하는 새 프로젝트를 만들어볼까 생각중인데이경우 파이어베이스나 node.js를 활용해서, 제가 직접 기본적인 백엔드만 구축하려고 하는 새 프로젝트가 취업에 도움이 될지 궁금합니다.. 비효율적인가 싶기도 하고요아니면 다른 좋은 방법이 있을까요..?
-
미해결파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트
makemigrations 실행 시 TypeError: 'module' object is not iterable 오
안녕하세요. 강사님.instagram 앱 생성 과 모델 생성 후 Migration 실행이 잘 안되네요.요런 에러를 만나고 있는데요. 실행 환경 문제 같기도 한데, 해결 방법을 잘 모르겠네요. 좀 힌트가 없을까요? ㅜㅜ
-
해결됨실무 환경 그대로 주문게시판 만들기 웹개발 기초 마스터
팝업 종료 콜백
부모에서 자식 팝업을 띄울 때,this.gfnOpenPopup("popup", "Board::OB_001_02.xfdl", oArg, sPopupCallBack, oOption);이렇게 사용한다고 하셨는데,sPopupCallBack 사용예시가 있을까요? 팝업 내에서 서버호출 후에 콜백함수 예시는 있는데, 자식 팝업에서 부모로 콜백시키는 함수(sPopupCallBack) 는 있는데 예시는 없어서요. 자식 팝업에서 수정완료 후 this.close(); 하면서 부모의 그리드(주문내역 조회)를 reload 하고싶습니다.
-
해결됨실무 환경 그대로 주문게시판 만들기 웹개발 기초 마스터
주문 수정 구현 강의 중 xml update 태그
주문 수정 구현 강의 중 xml에 update 쿼리 작성시 <update> 대신 <insert> 태그를 사용한 이유가 따로 있을까요?
-
미해결스프링부트 시큐리티 & JWT 강의
권한 인증 403가 뜹니다
https://github.com/bgseong/Security-test public class JwtAuthorizationFilter extends BasicAuthenticationFilter { private TokenService tokenService; public JwtAuthorizationFilter(AuthenticationManager authenticationManager, TokenService tokenService) { super(authenticationManager); this.tokenService = tokenService; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { super.doFilterInternal(request, response, chain); String token = tokenService.resolveToken(request); if(token == null){ chain.doFilter(request, response); return; } if (tokenService.validateToken(token)) { Authentication authentication = tokenService.getAuthentication(token); SecurityContextHolder.getContext().setAuthentication(authentication); System.out.println(SecurityContextHolder.getContext().getAuthentication()); } chain.doFilter(request,response); } }@EnableWebSecurity @Configuration @RequiredArgsConstructor @EnableGlobalMethodSecurity(prePostEnabled = true) public class SecurityConfig { @Autowired TokenService tokenService; @Autowired CorsConfig corsConfig; @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{ http .csrf().disable() .httpBasic().disable() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .formLogin().disable() .apply(new MyCustomDsl()) .and() .authorizeHttpRequests(authorize -> authorize .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll() // 특정 정적 리소스 허용 .requestMatchers("/api/v1/user/**").hasAnyRole("ADMIN", "MANAGER") .requestMatchers("/api/v1/manager/**").hasRole("ADMIN") .requestMatchers("/api/v1/admin/**").hasRole("ROLE_ADMIN") .anyRequest().permitAll()); return http.build(); } public class MyCustomDsl extends AbstractHttpConfigurer<MyCustomDsl, HttpSecurity> { @Override public void configure(HttpSecurity http) throws Exception { AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class); http .addFilter(corsConfig.corsFilter()) .addFilter(new LoginFilter(authenticationManager,tokenService)) .addFilter(new JwtAuthorizationFilter(authenticationManager,tokenService)); } } }@Component public class TokenService implements InitializingBean { private final UserRepository usersrepository; private final Logger logger = LoggerFactory.getLogger(TokenService.class); private static final String AUTHORITIES_KEY = "auth"; private final String secret; private final long accessTokenValidityInMilliseconds; private final long refreshTokenValidityInMilliseconds; public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String REFRESHTOKEN_HEADER = "RefreshToken"; private Key key; public TokenService( UserRepository usersrepository, @Value("${spring.jwt.secret}") String secret, @Value("${spring.jwt.token-validity-in-seconds}") long tokenValidityInSeconds) { this.usersrepository = usersrepository; this.secret = secret; this.accessTokenValidityInMilliseconds = tokenValidityInSeconds * 500; this.refreshTokenValidityInMilliseconds = tokenValidityInSeconds * 1000 * 336; } @Override public void afterPropertiesSet() { byte[] keyBytes = Decoders.BASE64.decode(secret); this.key = Keys.hmacShaKeyFor(keyBytes); } public String createAccessToken(PrincipalDetails principalDetails) { return createAccessToken(principalDetails.getUser().getEmail(), principalDetails.getAuthorities()); } public String createRefreshToken(PrincipalDetails principalDetails) { return createRefreshToken(principalDetails.getUser().getEmail(), principalDetails.getAuthorities()); } public String createAccessToken(String email, Collection<? extends GrantedAuthority> inputAuthorities) { String authorities = inputAuthorities.stream() .map(GrantedAuthority::getAuthority) .collect(Collectors.joining(",")); long now = (new Date()).getTime(); String accessToken = Jwts.builder() .setSubject(email) .claim(AUTHORITIES_KEY, authorities) .signWith(key, SignatureAlgorithm.HS512) .setExpiration(new Date(now + this.accessTokenValidityInMilliseconds)) .compact(); return accessToken; } public String createRefreshToken(String email, Collection<? extends GrantedAuthority> inputAuthorities) { String authorities = inputAuthorities.stream() .map(GrantedAuthority::getAuthority) .collect(Collectors.joining(",")); long now = (new Date()).getTime(); String Token = Jwts.builder() .setSubject(email) .claim(AUTHORITIES_KEY, authorities) .signWith(key, SignatureAlgorithm.HS512) .setExpiration(new Date(now + this.refreshTokenValidityInMilliseconds)) .compact(); return Token; } public Authentication getAuthentication(String token) { Claims claims = Jwts .parserBuilder() .setSigningKey(key) .build() .parseClaimsJws(token) .getBody(); User user = usersrepository.findByEmail(claims.get("sub",String.class)); Collection<? extends GrantedAuthority> authorities = Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(",")) .map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); PrincipalDetails principal = new PrincipalDetails(user); return new UsernamePasswordAuthenticationToken(principal, null, authorities); } public String resolveToken(HttpServletRequest request) { String bearerToken = request.getHeader(AUTHORIZATION_HEADER); if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { return bearerToken.substring(7); } return null; } public boolean validateToken(String token) { try { Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token); return true; } catch (io.jsonwebtoken.security.SecurityException | MalformedJwtException e) { logger.info("worng JWT sign"); } catch (ExpiredJwtException e) { logger.info("expire JWT"); } catch (UnsupportedJwtException e) { logger.info("No support JWT"); } catch (IllegalArgumentException e) { logger.info("JWT is worng"); } return false; } }이렇게 구성해 놨습니다. 그런데 모든 권한이 적용된 url에 접근을 하면 403 에러가 뜹니다.필터에서 SecurityContextHolder를 출력하면 아래와 같이 출력이 되는 걸 확인했고[Principal=com.securitytest.Securitytest.auth.PrincipalDetails@45095607, Credentials=[PROTECTED], Authenticated=true, Details=null, Granted Authorities=[ROLE_ADMIN]]컨트롤러에서 PrincipalDetails를 호출해보니, null이라서 오류가 난다고 뜹니다. 무엇이 문제일까요ㅠㅠ..
-
해결됨실전! FastAPI 입문
AssertionError: Expected 'undone' to be called once. Called 0 times.
def test_update_todo(client, mocker): ''' 특정 객체 update 테스트 # 200 ''' mocker.patch( "main.get_todo_by_todo_id", return_value= ToDo(id=1, contents="todo", is_done=True), ) undone = mocker.patch.object(ToDo, "undone") mocker.patch( "main.update_todo", return_value=ToDo(id=1, contents="todo", is_done=False), ) # API 호출 여부 response = client.patch("/todos/1", json={"is_done": False}) undone.assert_called_once_with() assert response.status_code == 200 # 성공 assert response.json() == {"id": 1, "contents": "todo", "is_done": False} # 성공 # Resetting the mock before the next scenario # 404 mocker.patch( "main.get_todo_by_todo_id", return_value=None, ) response = client.patch("/todos/1", json={"is_done": True}) assert response.status_code == 404 assert response.json() == {"detail": "ToDo Not Found"} pytest 시 아래와 같은 에러가 발생합니다. 강사님 코드와 상이한 부분도 없고 로직도 맞게 작성한 것 같은데 undone이 한번도 호출이 되지 않았다고 합니다.During handling of the above exception, another exception occurred: client = <starlette.testclient.TestClient object at 0xffff89948640>, mocker = <pytest_mock.plugin.MockerFixture object at 0xffff89004e50> def test_update_todo(client, mocker): ''' 특정 객체 update 테스트 # 200 ''' mocker.patch( "main.get_todo_by_todo_id", return_value= ToDo(id=1, contents="todo", is_done=True), ) undone = mocker.patch.object(ToDo, "undone") > print(undone.assert_called_once_with()) E AssertionError: Expected 'undone' to be called once. Called 0 times. tests/test_main.py:106: AssertionError ========================================================== short test summary info ========================================================== FAILED tests/test_main.py::test_update_todo - AssertionError: Expected 'undone' to be called once. Called 0 times. ======================================================== 1 failed, 5 passed in 0.18s ======================================================== #
-
해결됨PM을 위한 데이터 리터러시(프로덕트 데이터 분석)
A/B 테스트 설계시에 최소 샘플 사이즈의 달성이 너무 빠른 기간에 이루어지면 어떻게 하는게 좋나요?
안녕하세요! 강의 잘 듣고 있습니다. A/B 테스트 실험 기간에 대해 헷갈리는 부분이 있는데요!A/B 테스트 시에 검정력 분석(power-analysis)를 통해 통계적인 유의미함을 판단 가능한 최소 샘플 사이즈를 정하고, 그에 따라 며칠동안 테스트를 하는게 좋을지 정해놓고 테스트를 하는 것으로 알고 있습니다!여기서 궁금한 부분은 샘플 사이즈 계산기(검정력 분석)를 통해 나온 최소 샘플을 너무 단기간에 달성한다면 얼마 동안 실험을 지속하는게 좋을지인데요.예를 들어 샘플 사이즈 계산기를 통해, 최소 샘플 사이즈와 우리 서비스의 DAU 등을 고려해서 필요한 실험 기간이 "3일"이라는 결과가 나왔다면, 과연 3일만 실험하고 끝내면 되는지 입니다.이 때, '3일만 실험을 하면 너무 짧지 않나..? 단 3일 동안의 유저가 우리 서비스의 전체 유저들을 대표한다고 볼 수는 없는 것 같아. 게다가 평일과 주말의 유저 특성이 다른 부분도 고려를 해야지. 실험 기간을 7일로 해야겠다.' 라는 생각이 들었다고 가정해볼게요.최소 샘플 사이즈를 달성한 3일이 되었을 때 아래와 같은 결과가 나왔습니다. (아래 구체적인 값들은 예시일 뿐입니다!)A군과 B군의 전환율은 각 0.1%, 0.18%로 그 차이는 0.08%인데요. 이 때는 p-value가 0.1303으로 통계적으로 유의미한 차이가 아니라는 결과가 나왔습니다.그런데 7일이 지났을 때는 아래와 같은 결과가 나왔습니다.A군과 B군은 샘플 사이즈가 각 10,000명에서 20,000명으로 증가했을 뿐, 전환율은 각 0.1%, 0.18%로 그 차이가 0.08%로 이전과 동일했는데 샘플 사이즈가 증가했다는 이유로 p-value 0.0324가 되어 통계적으로 유의미한 차이라는 결과가 나타났어요.이런 경우에는 어떻게 해석을 해야 하는 걸까요..?3일의 결과(통계적으로 유의미한 차이가 아니다.)로 의사결정한다면 '3일은 너무 짧지 않나..? 그 3일 동안 접속한 유저가 우리 서비스의 유저를 대변한다고 볼 수 있을까?'라는 생각이 들 것 같고7일의 결과(통계적으로 유의미한 차이다.)로 의사결정한다면 '원래 통계적인 차이가 없는데, 내가 표본을 더 많이 수집함으로써 통계적으로 유의미한 차이가 있다고 만들어낸 것은 아닐까?(p-hacking은 아닐까?)'라는 생각이 들 것 같아요.
-
미해결프로그래밍 시작하기 : 파이썬 입문 (Inflearn Original)
맥에서 code 실행
파이썬을 처음 배우는 거라 첫 강의를 들었습니다!잘 실행되었는데 노트북을 껐다 키기만 하면 터미널에서 code를 쳤을 때 명령이 없다고 뜹니다그래서 vs code에서 shell command를 installed하면 EACCES: permission denied, unlink '/usr/local/bin/code'라고 뜹니다어떻게 해야 하나요?
-
미해결[중급편] 코인 가격 모니터링 앱 제작 (Android Kotlin)
인트로 화면 세팅에서 질문있습니다.
인트로화면이 뜨지를 않습니다.nav.xml입니다.
-
해결됨3. 웹개발 코스 [스프링 프레임워크+전자정부 표준프레임워크]
5강 /main5.do 호출시 화면이 안나옵니다
5강에서 오라클관련 설정및 연결을 완료하고/main5.do 호출시화면이 안뜨길래 디버깅해보니resultMap = mainService.selectMain(paramMap);실행시 Exception 이발생합니다아무리봐도 이상은없고 뭔가 설정에서 잘못건드렸나 싶어서 기존 프로젝트 삭제 후 강의파일의 5강6강 프로젝트를 임포트하였습니다 context-datasource.xml 의 url의 MYDB도 orcl 로 수정하였고 오라클접속시 아디비번도 다시한번 scott/tiger 확인하였습니다만왜 안되는지 모르겠습니다프로젝트클린, 메이브업데이트및클린,톰캣클린 3종클린 진행하여도 마친가지였습니다 이것저것하다가 해결했습니다오라클SID가 xe라 혹시나 orcl 말고 xe 넣으니까 되네요
-
미해결AWS Certified Solutions Architect - Associate 자격증 준비하기
수강신청 연장
안녕하세요 업무로 인해 집중 있게 수강하지 못했습니다수강연장 부탁드리겠습니다 감사합니다
-
미해결Practical Testing: 실용적인 테스트 가이드
섹션 2의 단위테스트 세분화하기에서요 !
public void add(Beverage beverage, int count) { if (count <= 0){ throw new IllegalArgumentException("음료는 1잔 이상 주문하실 수 있습니다."); } for (int i = 0; i < count; i ++) { beverages.add(beverage); } } // 위 코드랑 아래 테스트에 대해서 이해가 안되서요 ! @Test void add() { CafeKiosk cafeKiosk = new CafeKiosk(); Beverage latte = new Latte(); cafeKiosk.add(latte); int expectedSize = 1; int actuallySize = cafeKiosk.getBeverages().size(); String expectedName = "라떼"; String actuallyName = cafeKiosk.getBeverages().get(0).getName(); Assertions.assertThat(actuallySize).isEqualTo(expectedSize); Assertions.assertThat(actuallyName).isEqualTo(expectedName); } @Test void addSeveralBeverages() { CafeKiosk cafeKiosk = new CafeKiosk(); Beverage latte = new Latte(); cafeKiosk.add(latte, 2); Assertions.assertThat(cafeKiosk.getBeverages().get(0)).isEqualTo(latte); Assertions.assertThat(cafeKiosk.getBeverages().get(1)).isEqualTo(latte); } 저렇게 add()에 count를 넣어버리면 add()테스트에서 cafeKiosk.add(latte, 1)으로 수정하던지 해야 에러가 안나는 거 아닌가요? 강의에서는 그냥 진행하셔서 여쭤봅니다!
-
해결됨스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
${member.id}에서 import를 지워도 된다는 게 잘 이해가 안갑니다.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]누군가는 저게 Member객체라는 것을 알고 있어야 하지 않나요?jsp에서요.
-
해결됨핸드폰으로 내 음악 만들기 FL STUDIO 기초편
마이너
3부 도레미파솔라시도 부분 강의 중 마이너 부분이 하나도 이해가 안되네요. 3도,7도 플랫이 4화음이라는데 D major7이 어떻게 저렇게 되는지 이해가..안되네요
-
미해결[입문편] 안드로이드를 위한 코틀린(Kotlin) 문법
for 문 밖에서의 list 타입의 차이점
// 조건문// if else// whenfun main() { val testlist = mutableMapOf<String, Int>() testlist["a"] = 10 testlist["b"] = 50 testlist["c"] = 60 testlist["d"] = 100 testlist["e"] = 70 testlist["f"] = 30 // 50점이상 구하기 println(testlist.keys::class.java.simpleName) for (i in testlist){ println(i.key::class.java.simpleName) } } 위 코드처럼 작성 후 타입을 비교하였을 때 두가지의 타입이 다르게 나와있는데 그 이유를 모르겠습니다
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
Enum 리스트를 위한 엔티티를 만드는 방식이 궁금합니다.
엔티티에 Enum 클래스의 리스트를 포함시키려고 합니다.예를 들어서 Person이라는 엔티티가 Hobby라는 Enum 클래스의 리스트를 가질 때,PersonHobby라는 엔티티를 만들고 그 안에 Hobby를 적용시켜서 두 엔티티 사이의 연관관계를 만들려고 합니다.이 때, Person엔티티와 PersonHobby엔티티는 일대다 관계로 만드는 게 맞을까요? 다대다 관계로 만드는 게 맞을까요?하나의 동일한 취미를 여러 사람이 가질 수 있으니 다대다 관계일 수도 있다고 생각되는데, 이전에 값 타입 컬렉션 영상에서는 이러한 상황에서 일대다를 권장한다고 했기 때문에 헷갈려서 질문을 남깁니다.
-
미해결실전! Querydsl
현시점 QueryDSL에 대한 의견이 궁금합니다.
안녕하세요 김영한님!저는 2년차 백엔드 개발자 주니어입니다. 다름 아니라, QueryDSL이 2021년 5.0.0 버전 이후 새로 릴리즈되고 있지 않습니다.그래서 만약 새로운 서버에 대한 기술 스택을 정할 때, QueryDSL에 대한 영한님의 의견이 어떨지 궁금하여 글을 작성하게 되었습니다.("영한님 의견대로 도입한다 vs 안 한다" 같은 상황이 아니라 단순히 의견이 궁금한 겁니다!) 현재 거론되고 있는 대체 라이브러리는 대략 다음과 같은 것 같습니다.jooqkotlin-jdsl (코틀린 한정)MyBatis 만약 영한님이라면 현시점에서 QueryDSL을 선택하실 것 같나요? 다른 기준이 필요하다면 무엇일까요?혹은 요새 관심있는 라이브러리가 있으실까요?의견이 궁금합니다!감사합니다.
-
미해결한 입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지
onChange 작동 원리
좋은 강의 감사합니다.페이지 구현 - 홈 )/) 강의 중 23분에 onchange 설명해주신 것 관련해서 질문드립니다.DiaryList.js / 27번째 줄에 onChange로 setSortType을 전달했기 때문에 ControllMenu에서 onChange(e.target.value)의 값이 setSortType을 호출해서 sortType의 상태값이 변화하는 것으로 이해했습니다.즉 이렇게, onChange{setSortType("변화된 값")} 작동한걸로 이해했는데요. 27번째 줄에 onChange = {setSortType} 으로만 작성을 했는데 e.target.value라는 값이 전달된 것이 이해가 잘 안되어서 질문드립니다.만일 setSortType처럼 상태값을 받는 함수를 담고 있는 변수가 아닌const test = (a,b) => { console.log(a,b);}와 같은 매개변수를 2개를 받는 함수를 onchange로 호출한다고 하면 어떻게 넣을 수 있나요?
-
해결됨실전! Querydsl
fetchResults(), fetchCount() deprecated
안녕하세요countQuery 최적화까지 잘 들었는데요. queryDsl 특정버전 이상에서는 fetchResults(), fetchCount() 가 deprecated 되어었네요.그러면 앞으로 queryDsl 로 페이징을 처리할 때는.count(), content() 쿼리 동시에 X : searchPageSimple() 함수에서 사용한 fetchResult() 는 사용X 이므로.쿼리 최적화 방법도 X : 리턴값에 fetchCount() 를 사용해야 하므로.count(), content() 쿼리 별도로 날리고 (https://www.inflearn.com/questions/806452 참고) count() 쿼리시에는 sql의 count() 함수와 fetchOne() 을 사용한다.정리하면 3번의 방법을 사용하되, 이번 강의에서 말씀해주신 특정 조건에만 날아가는 쿼리도 사용은 못하는 것(fetchCount() Depcreaed 이므로) 맞을까요? 감사합니다.
-
해결됨생산성을 향상시키는 스프링부트 기반의 API 템플릿 프로젝트 구현
클라이언트에서 토큰을 서버로 줄 때
클라이언트(안드로이드)가 카카오에서 발급받은 엑세스토큰을 백으로 주는 상황일 때강의영상 토큰 발급 구현 (1), (2)는 작성하지 않아도 되는걸까요??