묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링부트 시큐리티 & JWT 강의
네이버 response 에 구글 이메일이 들어가 있는데
네이버로 회원가입 시getAttributes() 안 response 의 email에 구글메일이 들어가있는데왜그런지 아시는분 계신가요?
-
미해결지금 당장 NodeJS 백엔드 개발 [사주 만세력]
혹시 MySQL Workbench 신버젼에서도 가능하게 강의 내용 수정은 불가능할까요?
맥북 유저인데 8.0.20 버전을 실행하면 보안 이슈로 실행할 수 없다고 하네요 ㅠㅠ
-
해결됨[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
테스트 코드 깃헙
안녕하세요 혹시 테스트 코드나 service 코드는 깃헙에 따로 올라와있지는 않나요?https://github.com/ZeroCho/nodejs-book/tree/master/ch11/11.1/nodebird여기에는 안 보여서 질문합니다!
-
미해결스프링부트 시큐리티 & JWT 강의
Lombok 안되는 분들 참고
Lombok 안되시는 분들 있을 수 도 있어 남깁니다. 스프링부트 시작할 때 플러그인 넣어도 안되는 경우프로젝트 폴더 내 lombok 우클릭 -> Run As -> Java Application 눌러서 실행하면 설치 화면이 나옵니다.1. Specify location 누르신 후 IDE 실행파일 선택2. Install / Update 눌러서 실행3. Quit Installer 눌러서 나가기4. 이클립스 실행 하면 되는데 만약 이클립스 눌러도 반응이 없으신분들은이클립스 설치 폴더 안에 eclipse.ini 파일이 있습니다.눌러서 확인해보면 경로가 한글이 섞여 있는 경우는 이클립스 실행이 안되니 경로를 영어로 다 바꾸시면 됩니다. ※바탕화면이 한글로 되어 있는데 어떻게 Desktop 으로 바꾸죠 ??ㄴ 이건 인터넷 검색해보시면 되겠습니다. ※Lombok 설치 후 이클립스가 느려졌어요!!ㄴ eclipse.ini 파일 내부에-Xms256m-Xmx2048m여기 메모리 관련 부분을 수정-Xms2048m-Xmx4086m로 변경해서 사용하면 이전 처럼 빠르게 사용할 수 있습니다.
-
미해결스프링부트 시큐리티 & JWT 강의
SecurityConfig 작성할때 새로운 설정방법으로 해도 안돼요
.authorizeRequests()가 계속 빨간줄로 되는데 어떻게 해야하죠 ...?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
ES6 Sequelize.sync error
안녕하세요 현재 cjs 가 아닌 es6 로 nodejs 코드를 작성하고 있습니다. 9-2 강의 진행 중 강사님 깃헙 리포지토리 9-2 폴더 중 app.js 20번 줄에서 sequelize.sync is not a function 이라는 오류가 나옵니다. 구글 검색을 해본 결과 일부 블로그에서 es6 에서는 해당 함수를 사용이 불가하다는 글을 보았습니다. 그리고 models/index.js 파일에서 fs.readdirSync(__dirname) .filter(file=>{ return file.indexOf('.') !== basename && file.slice(-3) === '.js'; }) .forEach((file) =>{ import(path.join(__dirname,file)) .then((obj) => {console.log(obj.name); obj(sequelize, Sequelize.DataTypes); db[obj.name] = obj; obj.initiate(sequelize);}) .catch(err => console.log(err)); //const model = require(path.join(__dirname, file)); //console.log(file,model.name); //db[model.name] = model; //model.initiate(sequelize); });주석 처리한 부분은 cjs 스타일이고 변경한 부분은 동적 import 를 사용해서 구현해보았습니다. 구글 검색 후 obj(sequelize, Sequelize.DataTypes) 구문을 삽입하면 해당 오류가 해결이된다고 했으나 해결이 되지 않습니다. 오류설명이 구구절절 길었으나 제 질문을 정리하자면해당 함수(sequelize.sync)가 es6에서는 사용이 안되나요?사용이 안되다면 전면 cjs 로 바꿔 코드 작성을 해야하나요?입니다. es6 코드 작성을 연습하고자 코드를 변경해가며 진행중인데 난관을 겪었습니다. 질문 유의사항을 잘지켜야지 하며 적었는데 가독성이 있을지는 모르겠습니다. 감사합니다.
-
미해결지금 당장 NodeJS 백엔드 개발 [사주 만세력]
격국 질문 드립니다
본인 사주의 격국을 찾는 로직이나 알고리즘도 있을까요? 수강중인데 그부분에 대해서는 안나와 있는건가해서요!
-
해결됨스프링부트 시큐리티 & JWT 강의
role 컬럼은 꼭 들어가야하나요?
안녕하세요 강의내용보고 궁금해서 글 남깁니다!대부분 jwt 시큐리티를 구현할때 role이라는 컬럼을 넣으시는거 같은데왜 들어가야하는지 궁금합니다. 필수값인가요?감사합니다
-
해결됨Spring Boot JWT Tutorial
설명란이 대체 어디에 있죠?
코드를 복사 붙여 넣기 할 수 있도록설명란에 추가한다고 하셨는데대체 설명란이 어디에 있죠?목차에도 따로 없고강의 페이지의 휠을 내려도 따로 자료가 없는데요??알려주시면 감사하겠습니다..현재 Security 설정, Data 설정하는 부분에서지금 코드를 일일이 꾸역꾸역 치고있네요..자료 알려주시면 감사하겠습니다.
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
슬랙방에 들어가지지 않습니다
선생님 안녕하세요슬랙방 링크를 클릭하니 이런 페이지가 뜹니다.
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
/usr/local/etc/mongod.conf 파일이 없음
맥에서 vim /usr/local/etc/mongod.conf 를 입력했는데 기존 파일이 없어서 새로 작성되고, :wq!로도 저장이 안됩니다.그리고 애초에 /usr/local 밑에 etc 폴더가 없습니다. 어떻게 해결해야 하나요?위의 과정 없이 mongo admin -u를 진행하니 에러가 뜹니다.
-
해결됨[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
passport.authenticate('local/kakao') 관련 질문
안녕하세요routes/auth.js에서 passport.authenticate('local' / 'kakao')로 로그인전략을 실행할 때auth.js에서는 local(), kakao()가 있는 passport/index.js를 require 한 적이 없는데도 실행되는 걸 보고 질문드립니다.passport 모듈 내에 passport폴더를 자동으로 인식하는 기능이 있는건가요?
-
해결됨[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
const config = require('../config/config')[env];를 es모듈로 불러오는 방법
안녕하세요 자꾸 글 작성했다 지웠다 해서 죄송합니다.직접 검색해보고 해결해보려했는데 안되어서 다시 남깁니다. 7.6장 model/index.js 파일중에서const config = require('../config/config')[env];수업에 나왔던 이 코드와 동일하게 동작하게끔 es모듈 방식으로 import하는 코드를 작성하려 합니다import cfg from '../config/config.json' assert { type : 'json' } const config = cfg[env]; 이렇게 작성해 보았는데(node:10404) ExperimentalWarning: Importing JSON modules is an experimental feature and might change at any time(Use node --trace-warnings ... to show where the warning was created)이런 경고가 뜨고, 무시하고 app.js를 실행하면 서버가 실행되긴 하는데 책&예제코드에 나오는 메시지와는 다른 아래와 같은 메시지가 나옵니다.Executing (default): SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = 'users' AND TABLE_SCHEMA = 'nodejs'Executing (default): SHOW INDEX FROM users FROM nodejsExecuting (default): SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = 'comments' AND TABLE_SCHEMA = 'nodejs'Executing (default): SHOW INDEX FROM comments FROM nodejs 어떻게 해야 es모듈에서도 동일하게 동작하게끔 할 수 있는지 궁금합니다.
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
수업 내용에 대해 질문드립니다.
안녕하세요http.createServer(async (req, res) => { try { if (req.method === 'GET') { if (req.url === '/') { const data = await fs.readFile(path.join(__dirname, 'restFront.html')); res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); return res.end(data); } else if (req.url === '/about') { const data = await fs.readFile(path.join(__dirname, 'about.html')); res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); return res.end(data); } else if (req.url === '/users') { res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' }); return res.end(JSON.stringify(users)); } // /도 /about도 /users도 아니면 try { const data = await fs.readFile(path.join(__dirname, req.url)); return res.end(data); } catch (err) { // 주소에 해당하는 라우트를 못 찾았다는 404 Not Found error 발생 } restFront.js , restFront.css 등을 받아오는 try 부분에서강의에는 const data = await fs.readFile(`.${req.url)`);로 수업하셨는데책과 깃헙예제에는 const data = await fs.readFile(path.join(__dirname, req.url)); 로 되어있어가지구요1. .${req.url}에서 백틱과 .은 꼭 쓰여야 하는건지랑2. 책의 예제코드에서 __dirname의 경로는 restServer.js가 있는 위치가 기준이 되는건지 질문드립니다. else if (req.method === 'POST') { if (req.url === '/user') { let body = ''; // 요청의 body를 stream 형식으로 받음 req.on('data', (data) => { body += data; }); // 요청의 body를 다 받은 후 실행됨 return req.on('end', () => { console.log('POST 본문(Body):', body); const { name } = JSON.parse(body); const id = Date.now(); users[id] = name; res.writeHead(201, { 'Content-Type': 'text/plain; charset=utf-8' }); res.end('등록 성공'); }); } } return req.on('end', () =>{}) 에서 'end'라는 이벤트가 어느 부분에서 발생해서 저기 들어가는건지도 궁금합니다.
-
미해결스프링부트 시큐리티 & JWT 강의
강사님 질문이있습니다 ㅠㅠ
public class MyCustomDsl extends AbstractHttpConfigurer<MyCustomDsl, HttpSecurity> { @Override public void configure(HttpSecurity http) throws Exception { System.out.println("체크포인트!@@!@!@!@"); AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class); http .addFilter(new LoginFilter(authenticationManager)) .addFilterAfter(jwtFilter, UsernamePasswordAuthenticationFilter.class); } }를 구현하고, 로그인이 완료 되었을 때, @Override protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException { log.info("successfulAuthentication 함수 실행: 로그인 성공"); PrincipalDetails principalDetails = (PrincipalDetails) authResult.getPrincipal(); /* 로그인 완료, 1. 토큰 생성 2. 쿠키 장착 */ response.setHeader("gd", "gdgd"); // response.sendRedirect("/api/loginTest"); // super.successfulAuthentication(request, response, chain, authResult); }이 메서드 까지 구현했습니다. 제 원래 로직은액세스 토큰, 리프레쉬 토큰을 생성하고리프레쉬 토큰을 DB에 담고액세스 토큰, 레프레쉬 토큰 두 개를 쿠키에 저장하는 로직입니다. ResponseCookie build = ResponseCookie .from("accessToken", "gd") .path("/") .httpOnly(true) // 시간 .maxAge(JwtUtil.REFRESH_TOKEN_EXPIRE_TIME) .sameSite("Lax") .build(); ResponseEntity.ok().header("Set-Cookie", build.toString()) .body("ok");대충 쿠키를 생성해서 그 쿠키를 헤더에 담는 방식을 사용 중인데, 이렇게 로그인 완료 메서드에서 구현할 방법이 없고 헤더에 저장할 방법이 없어서 너무 막막합니다.. Controller에서 그냥 구현하면 ResponseEntity를 이용해서 헤더에 고정적으로 담을 수 있는데로그인 성공 메서드에서 어떻게 해야 이렇게 똑같이 구현을 할 수 있을까요..ㅠㅠㅜ?
-
미해결스프링부트 시큐리티 & JWT 강의
안녕하세요 강사님 질문이 있습니다.
loadUserByUsername 메서드를 구현하지 않아도로그인 기능, 권한 넘겨주기 다 가능할 거 같은데이 메서드가 꼭 필요한 이유가 있나요?doFilter를 안 탄다고 말씀해주셨는데전 JWT를 쿠키에 저장하는데,쿠키의 값이 없을 때 doFIlter를 그냥 빠져나가는 식으로 구현했습니다. successfulAuthentication이나, 권한을 UsernamePasswordAuthenticationToken authentication // = new UsernamePasswordAuthenticationToken(userId, null, List.of(new SimpleGrantedAuthority("ROLE_USER")));authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authentication); 이렇게 넣을 수 있던데 이러한 방식은 뭐가 잘못된 걸까요?문제가 생기나요?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
새로고침 한번에 클러스터 2개 종료
안녕하세요?setTimeout 대신 setImmediate를 적용해 요청이 발생하는 즉시 워커가 종료되게 해보았는데요, 이 경우엔 워커가 한번에 두개씩 종료됩니다.DevTool - network 창에 보이는 요청은 새로고침 1회당 GET 1회씩인데 왜 이러는지 궁금합니다! const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { console.log(`마스터 프로세스 아이디 : ${process.pid}`); // CPU 갯수만큼 워커를 생산 for (let i=0; i < numCPUs; i++ ){ cluster.fork(); } //워커가 종료되었을 때 cluster.on('exit', (worker, code, signal) => { console.log(`${worker.process.pid}번 워커가 종료되었습니다.`); console.log('code', code, `signal`, signal); }); } else { // 워커들이 포트에서 대기 http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8'}); res.write('<h1>Hello Node!'); res.end('<p>Hello Cluster!</p>'); setImmediate(()=> { process.exit(1); }); }).listen(8086); console.log(`${process.pid}번 워커 실행`); };
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
비동기 방식에서의 에러처리
안녕하세요! 어제 유투브에서도 질문드렸었는데 잘 이해가 가지 않아 다시 질문드립니다.184p server1-1.jsconst http = require('http'); const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.write('<h1>Hello Node!</h1>'); res.end('<p>Hello Server!</p>'); }); server.listen(8080); server.on('listening', () => { console.log('8080번 포트에서 서버 대기 중입니다!'); }); server.on('error', (error) => { console.error(error); });어제 이 부분 에러처리를 try/catch로 하면 안되는건지 질문드렸었는데 server함수가 비동기로 진행되는거라 try/catch 적용하면 안된다고 답변받았었습니다. 186p server2.jsconst http = require('http'); const fs = require('fs').promises; http.createServer(async (req, res) => { try { const data = await fs.readFile('./server2.html'); res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' }); res.end(data); } catch (err) { console.error(err); res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' }); res.end(err.message); } }) .listen(8081, () => { console.log('8081번 포트에서 서버 대기 중입니다!'); });그런데 바로 뒤에서 async를 사용하여 비동기임이 확실한데도 try/catch로 에러처리를 하신 부분이 나와서 잘 이해가 안갑니다..뒷부분에서는 왜 try/catch를 적용해도 되는건지 궁금합니다!
-
미해결스프링부트 시큐리티 & JWT 강의
마지막 강의 질문드립니다.
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { // 안 지우면 응답을 한번하고 아래서 두번하게 됨 오류가 됨 // super.doFilterInternal(request, response, chain); System.out.println("인증이나 권한이 필요한 주소 요청이 됨 "); String jwtHeader = request.getHeader("Authorization"); System.out.println("JWT HEADER :: {} " + jwtHeader); // JWT 토큰을 검증해서 정상적인 사용자인지 확인하기 if (jwtHeader == null || !jwtHeader.startsWith("Bearer")) { chain.doFilter(request, response); // 밑에 진행이 안되게 return; } String token = request.getHeader("Authorization").replace("Bearer ", ""); String username = JWT.require(Algorithm.HMAC512("cos")).build().verify(token).getClaim("username").asString(); // 서명이 정상적으로 됨 if (username != null) { User userEntity = userRepository.findByUsername(username); PrincipalDetails principalDetails = new PrincipalDetails(userEntity); // 임의의 authentication 만들기 username 이 null 이 아니라는게 인증이 된거임 // jwt 토큰 서명을 통해서 서명이 정상이면 Authentication 객체를 만들어준다 Authentication authentication = new UsernamePasswordAuthenticationToken(principalDetails, null, principalDetails.getAuthorities()); // 시큐리티 저장할 수 있는 세션 공간 //강제로 시큐리티의 세션에 접근하여 Authentication 객체를 저장 SecurityContextHolder.getContext().setAuthentication(authentication); } chain.doFilter(request, response); } @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.csrf().disable(); // 내 서버는 STATELESS http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .addFilterBefore(new JwtFilter(), SecurityContextHolderFilter.class) .addFilter(corsFilter) // CrossOrigin(인증X) 시큐리티필터에 등록인증(O) .addFilter(new JwtAuthenticationFilter(authenticationManager())) .addFilter(new JwtAuthorizationFilter(authenticationManager(), userRepository)) // CrossOrigin 정책 안쓰고 모든 요청 허용 .formLogin().disable() // 폼로그인 사용 안함 .httpBasic().disable() // http 로그인 방식 안쓰겠다 .authorizeHttpRequests(auth -> auth.requestMatchers("/api/v1/user/**").hasAnyRole("ROLE_USER", "ROLE_MANAGER", "ROLE_ADMIN") .requestMatchers("/api/v1/manager/**").hasAnyRole("ROLE_MANAGER", "ROLE_ADMIN") .requestMatchers("/api/v1/admin/**").hasRole("ROLE_ADMIN") .anyRequest().permitAll() ); return http.build(); }마지막 강의 실습을 하는데요 디버깅 하면 유저 정보 정보 및 권한이 잘 조회되고 있지만403 에러가 발생하고 있습니다.SecuriyConfig에는 deprecated 를 이유로 antMatchers가 아닌 저렇게 권한설정을 해주었는데요 잘못된 부분이 있는지 문의드립니다.
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
라우트 분리 및 템플릿 엔진 사용법 강의
안녕하세요. 이전 강의와 강의 교안과는 다르게, 개정3판 강의에서는 라우트분리 및 템플릿엔진 사용법과 관련된 강의가 빠져있더라고요.혹시 해당 강의들에 대해서 이번 개정판에서는 더 이상 학습하지 않아도 괜찮기 때문에 강의 내용에서 빠진 것 일까요?매번 좋은 강의로 감사합니다.