이번 시간에는 지난 시간에 이어 JWT token 을 사용하여 상태유지를 지속하고, 메세지를 보내는 과정을 설명할까 합니다.
앱에서 글 등록을 했을 경우, 누가 요청을 했는지 서버에 알리는 것은 token 을 통해서 알릴 수 있습니다.
token 은 쿠키나 localStorage 에 저장해 두고 이벤트 발생시 GET 이나 POST 방식으로 REQUEST 를 보내면 됩니다.
우선 글 등록이 발생했을 경우 서버쪽에서 처리해주는 프로그램 코드를 보여드리겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
function register_api_hooks() { register_rest_route( 'msgapi/v1', '/msg/add/', array('methods' => 'POST','callback' => 'add_msg') ); } function add_msg($request){ global $wpdb; $arr_header = get_nginx_headers(); $token = $arr_header['Authorization']; list(,$token) = explode('Bearer ',$token); $sql = " select user_id from wp_msgapi_token where token = '".esc_sql($token)."'"; $sender_id = $wpdb->get_var($sql); $receiver_id = $request['receiver_id']; $msg = $request['msg']; $ret = array(); if($sender_id && $receiver_id && $msg){ $sql = " INSERT INTO wp_msgapi_msg (sender_id, receiver_id, msg, is_read, read_date) VALUES ($sender_id, $receiver_id, '".esc_sql($msg)."', 0, null); "; $wpdb->query($sql); $msg_id = $wpdb->insert_id; $ret['msg_id'] = $msg_id; } else { if (!$receiver_id){ $ret['code'] = "no receiver id"; $ret['message'] = "There is no receiver ID"; } else if (!$msg){ $ret['code'] = "no msg"; $ret['message'] = "There is no Msg"; } else if (!$sender_id){ $ret['code'] = "auth_failed"; $ret['message'] = "Invalid Credentials"; } $ret['data'] = array("status"=>403); } return $ret; } |
서버 쪽에서는 HEADER 의 키값이 Authorization 인 값 중에서 Bearer 뒤에 나오는 토큰 값을 짤라서 DB에 그 값이 있는 user_id 를 찾아내면 됩니다.
인증과 관련된 Request Header 인 Authorization 을 파싱하기 위해 함수 하나를 만들어야 합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
function get_nginx_headers($function_name='getallheaders'){ $all_headers=array(); if(function_exists($function_name)){ $all_headers=$function_name(); } else{ foreach($_SERVER as $name => $value){ if(substr($name,0,5)=='HTTP_'){ $name=substr($name,5); $name=str_replace('_',' ',$name); $name=strtolower($name); $name=ucwords($name); $name=str_replace(' ', '-', $name); $all_headers[$name] = $value; } elseif($function_name=='apache_request_headers'){ $all_headers[$name] = $value; } } } return $all_headers; } |
그 후에는 글 등록한 사람을 sender_id 로 하여 저장하고 DB에 기록합니다.
마찬가지로 글 읽기 이벤트의 코드는 요청한 사람을 my_id 변수에 담고, receiver_id 가 my_id 인 것을 찾으면 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
add_action( 'rest_api_init', 'register_api_hooks' ); function register_api_hooks() { register_rest_route( 'msgapi/v1', '/msg/add/', array('methods' => 'POST','callback' => 'add_msg') ); } function read_msg($request){ global $wpdb; $arr_header = get_nginx_headers(); $token = $arr_header['Authorization']; list(,$token) = explode('Bearer ',$token); $sql = " select user_id from wp_msgapi_token where token = '".esc_sql($token)."'"; $my_id = $wpdb->get_var($sql); $sender_id = $request['sender_id']; $ret = array(); if($sender_id && $my_id){ $sql = " select id, sender_id, msg from wp_msgapi_msg where sender_id = ".$sender_id." and receiver_id = ".$my_id." and is_read = 0"; $ret = $wpdb->get_results($sql,ARRAY_A); $sql = " update wp_msgapi_msg set is_read = 1, read_date = NOW() where sender_id = ".$sender_id." and receiver_id = ".$my_id; $wpdb->query($sql); if(!$ret){ $ret['code'] = "no data"; $ret['data'] = array("status"=>404); $ret['message'] = "There is no data"; } } else { if (!$sender_id){ $ret['code'] = "no sender id"; $ret['message'] = "There is no sender ID"; } else if (!$my_id){ $ret['code'] = "auth_failed"; $ret['message'] = "Invalid Credentials"; } $ret['data'] = array("status"=>403); } return $ret; } |
그럼 POSTMan 으로 테스트를 해 볼까요?
테스트를 위해서 테이블에 user_id 1번이 4번에게 메세지를 보낸 데이타를 입력해 줍니다.
1 2 |
insert into wp_msgapi_msg ( sender_id, receiver_id, msg, is_read, read_date, add_date) VALUES ( 1, 4, '같이놀자!', 0, NULL,NOW()) |
POSTMan 으로는 4번 회원의 token 을 HEADER 에 넣어서 POST 에는 sender ID 를 1 인 회원의 정보를 요청합니다.
이것은 4번 회원과 1번 회원이 채팅하는 도중, 4번 회원이 1번 회원이 보낸 메세지를 보여주는 화면 구성에 사용하는 프로세스입니다.
이렇게 요청을 하면 4번 회원이 1번 회원이 보내온 메세지를 화면에 그리는 작업을 앱에서 수행할 수 있습니다.
단, sender_id 를 예측하기 힘들게 base64_encode 를 사용해도 좋습니다.
하지만 이 값을 제3자가 가로채거나 디버거툴로 분석한다 하더라도 해커에게 어떤 이익이 없기 때문에 암호화할 필요는 없습니다.
앱에서 드로잉하는 파트는 여러분들의 몫으로 남겨두고, WORDPRESS REST API 를 사용하여 JWT 토큰을 활용하고 API 서버 (백엔드) 구조 설계과 과정들에 관한 이야기를 마무리 하겠습니다.