묻고 답해요
158만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
tbl_todo 질문입니다
강의 12분 55초에malldb로 들어가서 tbl_todo가 떠야하는데 저는 없네요그래서 한참 이것저것 찾아보니까 tbl_todo가root/apidb/에 있네요.어디가 잘못된건가요?ㅜㅜ
-
해결됨코드로 배우는 React 19 with 스프링부트 API서버
수업 외 질문인데 'tbl'이 무슨 의미인가요???
Table 어노테이션에서 이름 지정 시 tbl 이라는 접두사가 붙었는데 무슨 의미가 있는건가요??
-
해결됨Spring Boot JWT Tutorial
3강 secret key 관련해서 질문있습니다
secret key 를 특정 문자열을 Base64로 인코딩 한거라고 하셨는데 어떤 문자열을 Base64로 인코딩해서 넣어야 하나요?
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
node.js 버전 및 typescript 적용 문의
안녕하세요 강사님.node.js 강의 수강을 이제 막 시작한 프론트엔드 개발자 수강생입니다.1. 모든 강의는 node.js 14 버전 기준으로 녹화가 된게 맞나요? 맞다면 22LTS 버전으로 설치해도 강의를 수강하는데 문제는 없을까요? 2. 그리고 프로젝트 생성 처음부터 typescript 적용하고 싶은데, 초보자에게 괜찮을까요?비추천이시라면 typescript 없이 시작하려고 합니다.감사합니다.
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
엔티티클래스에서 질문입니다
엔티티클래스 만들기 5분 20초경에 create table todo{ tno bigint ~~~~~ 이런식으로 떠야하는데}저는 jdbc url [Connecting through datasource 'HikariDataSource ~~~이런식으로 뜹니다~~~중간에 뭐가 잘못된거 같은데 어디를 수정해야하나요?
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
수정시 writer값이 삭제되는 오류
putOne의 파라미터로 todo를 넘기면 괜찮은데todoModify를 넘기면 writer가 삭제되는 오류가 생깁니다ㅠㅠㅠ todoModify를 따로 사용하는 건 코드안정성 때문인가요? const handleClickModify = () => { const todoModify: TodoModify = { tno: todo.tno, title: todo.title, dueDate: todo.dueDate, complete: todo.complete, }; //putOne(todoModify) 하면 writer가 삭제되는 오류수정 필요 putOne(todo).then((data) => { console.log("modify result : ", data); setResult("Modified"); }); };
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
12.7. 방장기능(강퇴) 질문드립니다.
socket.on('kicked', (data) => { console.log('강퇴 이벤트 수신'); alert(data.message); window.location.href = data.redirectUrl; }); socket.on('kickUser', (userId) => { console.log('강퇴 요청 받음:', userId); const targetSocket = chat.sockets.get(userId); if (targetSocket) { console.log('강퇴 대상 소켓 찾음'); targetSocket.emit('kicked', { message: '강퇴되었습니다.', redirectUrl: '/' }); setTimeout(() => { // 강퇴된 소켓 연결 해제 targetSocket.disconnect(true); console.log(`사용자 ${userId} 강퇴 완료`); }, 100); } else { console.log(`사용자 ${userId} 소켓을 찾을 수 없음`); } }); socket.on('kicked',가 작동을안하네요 서버쪽에서는 targetSocket.disconnect(true)정상작동합니다.
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
교안 31 오타 수정해주세요
page -> size리액트 잘 모르시는 분들은 에러가 아닌데 dtoList1개 오시면 한참 해매실 것 같네요,
-
미해결카카오,구글 SNS 로그인(springboot3, vue3)
소셜 로그인 설계
안녕하세요 강사님 혹시 oauth2 를 이용한 로그인을 한 다음에 사용자 프로필을 받는 것이 서비스 플로우인데 이럴경우 웹이 아닌 앱을 사용할경우 (로직은 다른 거 알고 있습니다.) (PCKE 방식 사용 예정입니다.)oauth2 를 해서 사용자 db에 저장이 되고 이렇게 처음에 저장이 되고 그 다음에 프로필을 받으면 저 값이 수정이 되게 만들어 주는 게 맞을지 질문드립니다. 사용자엔티티에 Provider 나 socialId 로 값을 받습니다. (구글과 애플을 사용할 예정입니다.) @Entity @Table(name = "users") @Getter @NoArgsConstructor @Setter public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id") private Long id; @Column(name = "name", nullable = false) private String name; @Enumerated(EnumType.STRING) @Column(name = "SEX", nullable = false) private Sex sex; @Column(name = "age", nullable = false) private Integer age; @Column(name = "nationality", nullable = false) private String nationality; @Column(name = "introduction", length = 40, nullable = false) private String introduction; @Column(name = "visit_purpose", length = 40, nullable = false) private String visitPurpose; @Column(name = "languages", nullable = false) private String languages; @Column(name = "hobby", nullable = false) private String hobby; @Column(name = "created_at", nullable = false) private Instant createdAt; @Column(name = "updated_at", nullable = false) private Instant updatedAt; @Column(name = "Provider", nullable = false) private String provider; @Column(name = "social_id", nullable = false) private String socialId; @Column(name = "email", nullable = false) private String email; @Builder public User(String name, Sex sex, Integer age, String nationality, String introduction, String visitPurpose, String languages, String hobby, String provider, String socialId, String email) { this.name = name; this.sex = sex; this.age = age; this.nationality = nationality; this.introduction = introduction; this.visitPurpose = visitPurpose; this.languages = languages; this.hobby = hobby; this.provider = provider; this.socialId = socialId; this.email = email; this.createdAt = Instant.now(); this.updatedAt = Instant.now(); } public void updateProfile(UserUpdateDTO dto) { if (dto.getName() != null && !dto.getName().trim().isEmpty()) { this.name = dto.getName().trim(); } if (dto.getSex() != null) { this.sex = dto.getSex(); } if (dto.getAge() != null) { this.age = dto.getAge(); } if (dto.getNationality() != null && !dto.getNationality().trim().isEmpty()) { this.nationality = dto.getNationality().trim(); } if (dto.getIntroduction() != null && !dto.getIntroduction().trim().isEmpty()) { this.introduction = dto.getIntroduction().trim(); } if (dto.getVisitPurpose() != null && !dto.getVisitPurpose().trim().isEmpty()) { this.visitPurpose = dto.getVisitPurpose().trim(); } if (dto.getLanguages() != null && !dto.getLanguages().trim().isEmpty()) { this.languages = dto.getLanguages().trim(); } if (dto.getHobby() != null && !dto.getHobby().trim().isEmpty()) { this.hobby = dto.getHobby().trim(); } this.updatedAt = Instant.now(); // 수정 시각 갱신 } }
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
쿠키에 accessToken, refreshToken을 담고, 조회 시에 undefined
쿠키안에 accessToken과 refreshToken을 JSON.stringfy()로 문자열로 담아주는데 getCookie()를 할시에 object타입으로 전달되어서 accessToken과 refreshToken이 undefined로 잡혀 갱신이안됩니다.
-
미해결카카오,구글 SNS 로그인(springboot3, vue3)
카카오 인가코드 요청
카카오 인가 코드 요청 url이 변경 된 것 같습니다!
-
해결됨카카오,구글 SNS 로그인(springboot3, vue3)
구글 로그인 프론트 화면
안녕하세요 구글 로그인 구현 중 질문있어서 질문드립니다! googleUrl, googleClientId, googleRedirectUrl, googleScope, googleResponseType 을 const auth_url = `${this.googleUrl}?client_id=${this.googleClientId}&redirect_url=${this.googleRedirectUrl}&response_type=code&scope=${this.googlescope}`; window.location.href = auth_url; 구글로그인 화면을 누르면 리다이렉트 url에 오류가 있다고 하는데 동일한 리다이렉트 url로 해도 잘 안됩니다 이럴 경우 또 어떤 것을 확인해보는게 좋을까요??
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
12.7 socket.js코드 그대로 뱃겨서 했는데, socket.request.session.color가안나오네요
socket.request.session은 서버쪽으로 잘 전달되는데, socket.request.session.color가 전달이안되네요 cors에러도 잡았는데 그래도 안잡히네요
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
12.7 코드 그대로 뱃겨서 햇는데 스샷같이 오류가뜹니다.
완전히 똑같이 복붙하고 실행했는데 계속 이메시지가 프론트엔트에 뜨네요
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
소셜 로그인 질문 있습니다
social 유저는 기존 회원보다 위험한 유저이므로 회원 정보 수정 페이지로 이동시켜야 한다 라고 하셨는데 이유가 뭔가요??
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
JWT 설정 후 JSON 데이터가 문자열로 옵니다...
📤 before requestjwtUtil.ts:30 ✅ Response ReceivedjwtUtil.ts:34 📦 Content-Type: application/jsonjwtUtil.ts:35 🧾 typeof res.data: stringcontent-type은 json 형식으로 맞춰 주었는데 정작 데이터가 String으로 와서 list에 뿌려주지를 못하고 있습니다.Postman으로 확인했을 때는 정상적으로 JSON 데이터를 반환받는데 리액트에서 확인할려면 res.data가 "{\"dtoList\":[{\"tno\":115,\"title\":\"123zzzㅋㅋㅋㅋ\",\"content\":null,\"complete\":false,\"dueDate\":\"2025-08-07\",\"writer\":\"123\"}위와 같이 스트링 형식으로 변환되어서 들어와서 오류가 생깁니다.어디가 문제일까요..ㅠㅠ
-
미해결[개정3판] Node.js 교과서 - 기본부터 프로젝트 실습까지
12.7.1스스로 해보기 질문되나요
//채팅창에 현재 참여자 수나 목록표시하기구현한chat.html코드와 socket.j코드입니다. 그런데 chat: ${socket.request.session.color} 이부분이 undefined으로 계속 나옵니다. console.log에 찍어보면 socket.request.session에 color만 빼고 나오네요.{% extends 'layout.html' %} {% block content %} <h1>{{title}}</h1> <a href="/" id="exit-btn">방 나가기</a> <fieldset> <legend>채팅 내용</legend> <div style="display: flex; gap: 20px;"> <!-- 채팅 목록 --> <div id="chat-list" style="flex: 3;"> {% for chat in chats %} {% if chat.user === user %} <div class="mine" style="color: {{chat.user}}"> <div>{{chat.user}}</div> {% if chat.gif %} <img src="/gif/{{chat.gif}}"> {% else %} <div>{{chat.chat}}</div> {% endif %} </div> {% elif chat.user === 'system' %} <div class="system"> <div>{{chat.chat}}</div> </div> {% else %} <div class="other" style="color: {{chat.user}}"> <div>{{chat.user}}</div> {% if chat.gif %} <img src="/gif/{{chat.gif}}"> {% else %} <div>{{chat.chat}}</div> {% endif %} </div> {% endif %} {% endfor %} </div> <!-- 참여자 목록 --> <div style="flex: 1;"> <h3>참여자</h3> <ul id="user-list"></ul> </div> </div> </fieldset> <form action="/chat" id="chat-form" method="post" enctype="multipart/form-data"> <label for="gif">GIF 올리기</label> <input type="file" id="gif" name="gif" accept="image/gif"> <input type="text" id="chat" name="chat"> <button type="submit">전송</button> </form> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> const socket = io.connect('http://localhost:8005/chat', { path: '/socket.io', transports: ['websocket'] }); socket.emit('join', new URL(location).pathname.split('/').at(-1)); socket.on('join', function (data) { const div = document.createElement('div'); div.classList.add('system'); const chat = document.createElement('div'); chat.textContent = data.chat; div.appendChild(chat); document.querySelector('#chat-list').appendChild(div); if (data.userList) { const ul = document.querySelector('#user-list'); // 참여자 목록이 들어갈 ul ul.innerHTML = ''; // 기존 목록 초기화 data.userList.forEach(function (user) { const li = document.createElement('li'); li.textContent = user; ul.appendChild(li); }); } }); socket.on('exit', function (data) { const div = document.createElement('div'); div.classList.add('system'); const chat = document.createElement('div'); chat.textContent = data.chat; div.appendChild(chat); document.querySelector('#chat-list').appendChild(div); }); socket.on('chat', function (data) { const div = document.createElement('div'); if (data.user === '{{user}}') { div.classList.add('mine'); } else { div.classList.add('other'); } const name = document.createElement('div'); name.textContent = data.user; div.appendChild(name); if (data.chat) { const chat = document.createElement('div'); chat.textContent = data.chat; div.appendChild(chat); } else { const gif = document.createElement('img'); gif.src = '/gif/' + data.gif; div.appendChild(gif); } div.style.color = data.user; document.querySelector('#chat-list').appendChild(div); }); document.querySelector('#chat-form').addEventListener('submit', function (e) { e.preventDefault(); if (e.target.chat.value) { axios.post('/room/{{room._id}}/chat', { chat: this.chat.value, }) .then(() => { e.target.chat.value = ''; }) .catch((err) => { console.error(err); }); } }); document.querySelector('#gif').addEventListener('change', function (e) { console.log(e.target.files); const formData = new FormData(); formData.append('gif', e.target.files[0]); axios.post('/room/{{room._id}}/gif', formData) .then(() => { e.target.file = null; }) .catch((err) => { console.error(err); }); }); </script> {% endblock %} const SocketIO = require('socket.io');const { removeRoom } = require('./services'); module.exports = (server, app, sessionMiddleware) => { const io = SocketIO(server, { path: '/socket.io',transports: ['websocket'] }); app.set('io', io); const room = io.of('/room'); const chat = io.of('/chat'); const wrap = middleware => (socket, next) => middleware(socket.request, {}, next); chat.use(wrap(sessionMiddleware)); room.on('connection', (socket) => { console.log('room 네임스페이스에 접속'); socket.on('disconnect', () => { console.log('room 네임스페이스 접속 해제'); }); }); chat.on('connection', (socket) => { console.log('chat 네임스페이스에 접속'); console.log(socket.request.session); socket.on('join', (roomId) => { socket.join(roomId); const room = socket.adapter.rooms.get(roomId); // Set const userList = room ? Array.from(room) : []; // 시스템 메시지 + 사용자 목록 전송 socket.to(roomId).emit('join', { user: 'system', chat: `${socket.request.session.color}님이 입장하셨습니다.`, userList, }); }); socket.on('disconnect', async () => { console.log('chat 네임스페이스 접속 해제'); const { referer } = socket.request.headers; // 브라우저 주소가 들어있음 const roomId = new URL(referer).pathname.split('/').at(-1); const currentRoom = chat.adapter.rooms.get(roomId); const userCount = currentRoom?.size || 0; if (userCount === 0) { // 유저가 0명이면 방 삭제 await removeRoom(roomId); // 컨트롤러 대신 서비스를 사용 room.emit('removeRoom', roomId); console.log('방 제거 요청 성공'); } else { socket.to(roomId).emit('exit', { user: 'system', chat: `${socket.request.session.color}님이 퇴장하셨습니다.`, }); } }); });}
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
loginSlice에서 reject가 반환되지 않습니다.
로그인시에 잘못된 아이디 비밀번호를 넣게 되면 콘솔 로그 창에 reject가 반환되어야 하는데 전부 fulfilled로 반환됩니다. 혹시 코드 필요하시면 첨부하도록 하겠습니다.
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
강사님 질문 있습니다.
이미지를 저장할 때 이미지 파일을 저장할 때가 있고 이미지 이름을 저장할 때가 있다고 하셨는데그러면 이미지를 파일 시스템이나 DB상에 저장을 하므로 그 파일에 접근하기 위해서 DB상에 이미지 이름을 저장한다고 생각하면 될까요?제가 생각한게 맞는지 궁금합니다.
-
미해결코드로 배우는 React 19 with 스프링부트 API서버
delete에 대한 테스트를 진행하지 않는 이유가 뭔가요??
테스트 코드 상에 있는 테스트 데이터를 지우는 것이므로 딱히 별 영향이 없지 않나요?