창작에 관련된 질문이나 간단한 팁, 예제를 올리는 곳
문제점:
클라이언트 <-> 서버 통신을 하면서 다음과 같이 메세지를 주고받기로 함
패킷종류|파라미터1|파라미터2
예)
MOTDREQ -> 서버에 MOTD를 요청 (파라미터 없음)
MOTD|공지사항입니다 -> MOTD는 "공지사항입니다" 임 (파라미터 1개)
MSG|김덕배|안녕하세요 -> 닉네임이 "김덕배" 인 사용자가 "안녕하세요" 라는 메세지를 보냄
그런데 공지사항이나 사용자 닉네임같은 경우 사용자가 마음대로 정할 수 있는 입력값이고
따라서 닉네임을 김덕|배 같은 걸로 지으면 MSG|김덕|배|안녕하세요 이런 메세지가 보내질거고
메세지 구조가 망쳐지고 잠재적인 오류가 발생할 수 있는 가능성이 있음
해결방법:
구분자로 사용되는 문자를 다 걸러내고 그런 솔루션을 생각했는데
그냥 사용자한테 입력받아서 오염의 껀덕지가 있는 문자들을 Base64 등으로 인코딩해서 보내고 받을 때 디코딩하면 끝임
MSG|김덕|배|안녕하세요
->
MSG|6rmA642VfOuwsA==|7JWI64WV7ZWY7IS47JqU
캐릭터이름도 DB에 저장할때 캐릭터명이 '); DROP TABLE USER; -- 이따구일 경우에 DB에 저장하는 쿼리를 날릴경우 문제가 생길 수 있는데
저걸 그대로 저장하지 말고 Jyk7IERST1AgVEFCTEUgVVNFUjsgLS0= 로 저장하고 주고받고, 사용자한테 보여줄때만 복호화하면 됨
(캐릭터 이름에 사용할 수 있는 언어나 문자셋을 제한하는 건 보안상의 이유 말고 미관상의 이유로도 필요하겠지만 대충 이런방법도 있다는거임)
illegal character 방지와 별개로 "MSG|김덕배|안녕하세요" 에 대해 얘기해보자면 "김덕배"는 보낼 필요가 없습니다.
클라이언트가 접속할 때마다 해당 클라이언트 전용소켓이 만들어집니다.
그걸 서버에서 관리하고 있다면, 누가 보냈는지는 서버에서 알 수 있습니다.
보내는 사람의 이름, 보내는 사람의 ID 등을 메시지에 의존하는 것은 안전하지 않습니다.
물론 우리가 만드는 게임 수준에서 "김덕배"를 "홍길동"으로 변조해서 보낼 클라이언트는 없습니다.
그냥 소켓 통신에 대해서 팁을 드리고자 하는 것입니다.
만약 MAP1이라는 공간에서 x10,y10 위치에 존재하는 사용자가 오른쪽으로 한칸 이동한다면?
MOVE|RIGHT 만 보내면 됩니다.
그런데 MOVE|김덕배|MAP1|x10,y10|RIGHT 이렇게 보낼 건가요?
김덕배, MAP1, x10,y10 은 서버가 갖고 있어야 합니다.
클라이언트가 소켓으로 어떤 메시지를 보내건, 서버는 "응, 김덕배가 뭔가를 보냈네. 얘는 현재 MAP1에 있고, x좌표 10, y좌표 10에 있는 친구네."라고 알 수 있게 구조를 만들어야 합니다.
보안상으로도 안전하지만 보안상 안전하다 얘기를 하는 게 아니라,
코딩을 할때 훨씬 간결해지고 소켓 통신하는 내용도 훨씬 단순해져서
게임 개발 퍼포먼스가 올라가실 겁니다.