프로젝트 구조 상 사용자는 jwt로 인증하고, 관리자는 session으로 인증하게 구현하였다.
socket 통신도 이와 같은 방향으로 구축하기로 했다.
사용자/관리자의 namespace
를 나누고, 사용자 쪽으로 연결 요청이 오면 jwt 인증을, 관리자쪽으로 연결요청이 오면 session 인증하도록 말이다.
구현
socket 통신 socket.io
라이브러리를 사용하여 구현하였다.
const io = require('socket.io')(server);
var userio = io.of('/user'),
managerio = io.of('/manager');
우선 사용자와 관리자의 namespace를 나눈다.
사용자 jwt 인증
io.on('connection', async (socket) => {
try { // jwt가 header로 왔는지 확인하여 user 인증
var user = myDecoder(socket.handshake.headers.authorization.split('Bearer ')[1]);
socket.join(user.doom_id); // 사용자 분류를 위해 room 입장
console.log('user connected to socket:', user);
}
catch(err) { // 인증 실패
console.log('authorization failed!', err);
socket.disconnect(0);
}
...
Authorization Header로 온 jwt를 socket에서 가져오는 것은 어렵지 않다.
socket.handshake.headers.authorization
로 바로 가져올 수 있다!
이후엔 가져온 jwt를 적절히 Parsing하면 된다.
jwt가 없거나 유효하지 않다면 socket 연결을 끊어버린다.
관리자 session 인증
session 인증은 간단하지 않다.
passport와 socket.io를 연동해줘야 하는데, 이를 위해 passport.socketio 라이브러리를 사용한다.
const passportSocketIo = require("passport.socketio");
const io = require('socket.io')(server);
const FileStore = require("session-file-store")(session);
io.use(passportSocketIo.authorize({
cookieParser: require('cookie-parser'),
key: 'express.sid',
secret: process.env.COOKIE_SECRET,
store: new FileStore(),
success: onAuthorizeSuccess,
fail: onAuthorizeFail,
}));
function onAuthorizeSuccess(data, accept){
accept(null, true);
}
function onAuthorizeFail(data, message, error, accept){
accept(null, false);
}
managerio.on('connection', async (socket) => {
try { // 연결 요청 시 관리자 인증 과정
var { salt, enc_pwd, ...manager } = socket.request.user;
console.log('manager connected to socket:', manager);
}
catch(err) { // 인증 실패
console.log('authorization failed!', err);
socket.disconnect(0);
}
...
io.use(passportSocketIo.authorize()
로 server passport와 연동해준다.
session이 server에 저장되어 있으면 onAuthorizeSuccess()
가 호출되고, 저장되어있지 않다면 onAuthorizeFail()
가 호출된다.
중요한 점은 session을 메모리에 저장하면 해당 라이브러리가 정상 작동하지 않는다! 꼭 DB나 FileStorage에 저장하도록 하자.
'대회, 프로젝트 > 2021 군장병 해커톤' 카테고리의 다른 글
[Vue.js, Node.js] passport.socketio cors issue (0) | 2021.10.14 |
---|---|
[Vue.js] Socket.io 연결 Issue 해결 (0) | 2021.10.12 |
[Docker / M1 sillicon] MySQL Build Error, 컨테이너 내에서 한글 입력 (0) | 2021.10.09 |
[pm2] 502 Bad Gateway 해결 (0) | 2021.10.07 |
[MYSQL] 가장 최근 삽입한 row 가져오기 (0) | 2021.10.06 |
Comment