http://stackoverflow.com/questions/16729992/authenticating-with-meteor-via-ddp-and-srp
Basic Auth로 websocket frame을 떠봤더니
o
1
오전 1:47:09
a["{\"server_id\":\"X43fG44wD7iJNCdoq\"}"]
42
오전 1:47:09
["{\"msg\":\"connect\",\"version\":\"pre1\",\"support\":[\"pre1\"]}"]
69
오전 1:47:09
["{\"msg\":\"sub\",\"id\":\"8jW8AaNcWf2iRhXWC\",\"name\":\"meteor.loginServiceConfiguration\",\"params\":[]}"]
110
오전 1:47:09
a["{\"msg\":\"connected\",\"session\":\"ZddaS7aatWT4i8nAR\"}"]
62
오전 1:47:09
a["{\"msg\":\"added\",\"collection\":\"users\",\"id\":\"aHC7AHZXbnhs7Efs9\",\"fields\":{\"username\":\"mone\",\"profile\":{\"photoSmall\":\"/image/tempImage/member_photo_placeholder.png\"}}}"]
192
오전 1:47:09
a["{\"msg\":\"added\",\"collection\":\"users\",\"id\":\"HuL3adLrtPKMoFWMK\",\"fields\":{\"profile\":{\"photoSmall\":\"/image/tempImage/member_photo_placeholder.png\"},\"username\":\"admin\"}}"]
193
오전 1:47:09
a["{\"msg\":\"added\",\"collection\":\"users\",\"id\":\"MZqYAk6C9kYao3ATz\",\"fields\":{\"profile\":{\"photoSmall\":\"/image/tempImage/member_photo_placeholder.png\"},\"username\":\"spectrum\"}}"]
196
오전 1:47:09
a["{\"msg\":\"ready\",\"subs\":[\"8jW8AaNcWf2iRhXWC\"]}"]
----------------------------------------------------------------------
여기까지 로그인 전
----------------------------------------------------------------------
"{\"msg\":\"method\",\"method\":\"login\",\"params\":[{\"srp\":{\"M\":\" \"}}],\"id\":\"2\"}"]
158
오전 1:48:22
a["{\"msg\":\"changed\",\"collection\":\"users\",\"id\":\"MZqYAk6C9kYao3ATz\",\"fields\":{\"emails\":[{\"address\":\"spectrick@gmail.com\",\"verified\":false}]}}"]
163
오전 1:48:22
a["{\"msg\":\"ready\",\"subs\":[\"8jW8AaNcWf2iRhXWC\"]}"]
57
오전 1:48:22
a["{\"msg\":\"updated\",\"methods\":[\"2\"]}"]
46
오전 1:48:22
a["{\"msg\":\"result\",\"id\":\"2\",\"result\":{\"token\":\"oGyFPfZM3c95yXw7M\",\"id\":\"MZqYAk6C9kYao3ATz\",\"HAMK\":\"b372e317d359b294cd9c5a4ca39c8f5523c310288661eba731191e2b4614ef17\"}}"]
190
오전 1:48:22
h
뭐 대략 이렇게 나오는데
a는 응답일테고
순서대로 보면
1. Connect 요구
{ msg: 'connect',
version: 'pre1',
support: [ 'pre1' ] }
이건 간단한데
{msg: "connected", session: "4vXhahuK5GTNzcC4S"}
이런 식으로 응답이 오면 오케이
2. 인증설정요구
{ msg: 'sub',
id: 'xaiCo33DPqaEJhkbc', /* id는 UUID. 아무거나 넣어도 된다. */
name: 'meteor.loginServiceConfiguration',
params: [] }
잠시 삼천포
UUID 생성은
Meteor.uuid = function () {
var HEX_DIGITS = "0123456789abcdef";
var s = [];
for (var i = 0; i < 36; i++) {
s[i] = Random.choice(HEX_DIGITS);
}
s[14] = "4";
s[19] = HEX_DIGITS.substr((parseInt(s[19],16) & 0x3) | 0x8, 1);
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
}
Random.choice = function (arrayOrString) {
var index = Math.floor(Random.fraction() * arrayOrString.length);
if (typeof arrayOrString === "string")
return arrayOrString.substr(index, 1);
else
return arrayOrString[index];
}
이런 식이다.
아무튼 sub 즉 subscribe 메시지로 meteor.loginServiceConfiguration 이란 이름의 collection을 구독 요청하면
{ server_id: 'X43fG44wD7iJNCdoq' }
{ msg: 'connected', session: 'EzRf563xHiK7J2FDo' }
{ msg: 'added',
collection: 'users',
id: 'aHC7AHZXbnhs7Efs9',
fields:
{ username: 'mone',
profile: { photoSmall: '/image/tempImage/member_photo_placeholder.png' } } }
{ msg: 'added',
collection: 'users',
id: 'HuL3adLrtPKMoFWMK',
fields:
{ profile: { photoSmall: '/image/tempImage/member_photo_placeholder.png' },
username: 'admin' } }
{ msg: 'added',
collection: 'users',
id: 'MZqYAk6C9kYao3ATz',
fields:
{ profile: { photoSmall: '/image/tempImage/member_photo_placeholder.png' },
username: 'spectrum' } }
{ msg: 'ready', subs: [ '1' ] }
유저명이 나오고, 'ready'를 받으면 끝. atmosphere.meteor.com 은 user 명을 보내지 않더라. 뭔가 설정이 있을 듯.
보내는게 무엇인지 살펴보니
{ msg: 'method',
method: 'login',
params: [ { srp:
"M":"HASHHASHHASHHASHHASHHASHHASHHASHHASHHASH"
} ],
id: '2' }
이렇다.
참고로 atmosphere는
{ msg: 'method',
method: 'login',
params:
[ 'atm',
'0.1.0',
{ srp:
"M":"HASHHASHHASHHASHHASHHASHHASHHASHHASHHASH"
} ],
} ],
id: '2' }
뭔가 조금 더 있다.
요걸 보내면 된다는 말인데
M에 사용자계정과 암호를 잘 어떻게 해서 응답이 돌아오면 되겠다.
M에 해당하는 부분은 SRP라는 것으로 암호화되어있는데
이걸 사용하면 된다.
로직은 그냥 소스 읽자.
nextid = 0
connected = false;
ws = require 'ws'
ws = new ws 'ws://localhost:3000/websocket'
ws.on 'open', ->
console.log "open socket"
ws.send JSON.stringify
msg: 'connect'
version: 'pre1'
support: ['pre1']
ws.on 'message', (data, flags)->
dataJSON = JSON.parse data
console.log dataJSON
if dataJSON.msg is 'connected'
connected = true
ws.send JSON.stringify
msg: 'sub'
id: (++nextid).toString()
name: 'meteor.loginServiceConfiguration'
if dataJSON.msg is 'ready'
ws.send JSON.stringify
msg: 'method'
method: 'login',
params: [
srp:
M: "*이 부분에 SRP로 인코딩"
]
id: '2'
해봤는데 잘 안된다.
사실 이 부분이 핵심인데 Basic auth / OAuth 도 다 다를것이다.
OAuth를 쓰면 어짜피 웹으로 왔다갔다 해야해서 모바일 등에서 쓰기 곤란할 듯.
그럼 로그인은 웹에서 하고 인증된 후에 재로그인이 가능한지 확인해보자.
{ msg: 'method',
method: 'login',
params: [ { resume: 'MvzqjyYD9bCs3rrcb' } ],
id: '1' }
resume 값을 기억하고 있으면 되는가보다 리프레쉬 했는데 같은 값을 반환한다.
open socket
{ server_id: 'X43fG44wD7iJNCdoq' }
{ msg: 'connected', session: 'ggEMcek5WmGD9vJSG' }
{ msg: 'added',
collection: 'users',
id: 'aHC7AHZXbnhs7Efs9',
fields:
{ username: 'mone',
profile: { photoSmall: '/image/tempImage/member_photo_placeholder.png' } } }
{ msg: 'added',
collection: 'users',
id: 'HuL3adLrtPKMoFWMK',
fields:
{ profile: { photoSmall: '/image/tempImage/member_photo_placeholder.png' },
username: 'admin' } }
{ msg: 'added',
collection: 'users',
id: 'MZqYAk6C9kYao3ATz',
fields:
{ profile: { photoSmall: '/image/tempImage/member_photo_placeholder.png' },
username: 'spectrum' } }
{ msg: 'ready', subs: [ '1' ] }
{ msg: 'changed',
collection: 'users',
id: 'MZqYAk6C9kYao3ATz',
fields: { emails: [ [Object] ] } }
{ msg: 'ready', subs: [ '1' ] }
{ msg: 'updated', methods: [ '11' ] }
{ msg: 'result',
id: '11',
result: { token: 'MvzqjyYD9bCs3rrcb', id: 'MZqYAk6C9kYao3ATz' } }
{ msg: 'result',
id: '11',
result: { token: 'MvzqjyYD9bCs3rrcb', id: 'MZqYAk6C9kYao3ATz' } }
{ msg: 'updated', methods: [ '11' ] }
음 token 이 어짜피 있어서 의미없나?
암튼 전체 소스
nextid = 0
connected = false;
ws = require 'ws'
ws = new ws 'ws://localhost:3000/websocket'
ws.on 'open', ->
console.log "open socket"
ws.send JSON.stringify
msg: 'connect'
version: 'pre1'
support: ['pre1']
ws.on 'message', (data, flags)->
dataJSON = JSON.parse data
console.log dataJSON
if dataJSON.msg is 'connected'
connected = true
ws.send JSON.stringify
msg: 'sub'
id: (++nextid).toString()
name: 'meteor.loginServiceConfiguration'
if dataJSON.msg is 'ready'
ws.send JSON.stringify
msg: 'method'
method: 'login',
params: [
resume: 'MvzqjyYD9bCs3rrcb'
]
id: '1'
댓글
댓글 쓰기