2011/11/24 11:44

웹로그 시각화 솔루션 - Logstalgia, website access log visualization

크리에이티브 커먼즈 라이선스
Creative Commons License

웹로그 시각화 솔루션 - Logstalgia, website access log visualization

Logstalgia (aka ApachePong) is a website access log visualization tool.

Logstalgia 는 웹로그를 시각화 하여 마치 핑퐁 게임을 보는듯한 시각영상을 제공합니다.

Description

Logstalgia is a website traffic visualization that replays or streams web-server access logs as a pong-like battle between the web server and an never ending torrent of requests.

Requests appear as colored balls (the same color as the host) which travel across the screen to arrive at the requested location. Successful requests are hit by the paddle while unsuccessful ones (eg 404 - File Not Found) are missed and pass through.

The paths of requests are summarized within the available space by identifying common path prefixes. Related paths are grouped together under headings. For instance, by default paths ending in png, gif or jpg are grouped under the heading Images. Paths that don’t match any of the specified groups are lumped together under a Miscellaneous section.

Requirements

Logstalgia requires a video card supporting OpenGL. For this reason you should typically run Logstalgia on your workstation rather than on the web-server itself (unless your workstation is the web-server).

As Logstalgia is designed to playback logs in real time you will need a log from a fairly busy web-server to achieve interesting results (eg 100s of requests each minute).

An example access log is included.

윈도우 / Mac / 리눅스용 프로그램을 제공하며,

웹서버에서 생성된 web log를 넣으면 아래와 같이


시각화 할 수 있습니다. 왼쪽의 공들이 사용자의 요청, 오른쪽 중간에 위아래로 움직이는 작은 상자가 서버의 처리 프로세서입니다.

오른쪽 아래의 큰 숫자 카운터는 서버로 들어온 요청수를 표시하고 있습니다.

저작자 표시 비영리 변경 금지

Trackback 0 Comment 0
2011/11/17 18:34

[소셜(SNS)댓글] 싸이월드-C로그 연동 FAQ

크리에이티브 커먼즈 라이선스
Creative Commons License

--------------------------------------------------------------------------------------------------------

요즘 소셜(SNS)댓글 시스템이 커뮤니티 사이트에서 관심을 받고 있습니다.

이전에 IT관련 회사들은 어떻게 하면 회원가입률을 높일까를 고민하다 이제는 어떻게 하면 커뮤니티를 활성화 시킬 수 있을까로 고민이 바뀌고 있죠. 말 그대로 좋은 정보를 제공하는 것도 중요하지만, 방문자의 호응을 쉽게 이끌어내기 위한 노력으로 SNS 댓글시스템이 각광을 받고 있지 않나 싶습니다.

각 SNS(트위터, 페이스북, 미투데이, 요즘 등) 서비스들의 로그인 API연동에 대한 FAQ를 정리해보도록 하겠습니다.

개발하실 분들은 참조해서 도움이 되셨으면 좋겠습니다.

--------------------------------------------------------------------------------------------------------

싸이월드(네이트) - C로그의 경우 OAuth 라이브러리를 제공하므로 쉽게 연동이 가능합니다.

아래는 라이브러리를 바탕으로 만든 연동 API 샘플입니다.

우선 네이트 개발자센터(http://devsquare.nate.com/)를 통해 개발자등록을 하고 Consumer key 발급 신청합니다.

발급받은 키를 통해 아래 소스를 변경하여 적용합니다.

------------------

index.php

------------------

<?php
header("expires: Thu, 19 Nov 1981 08:52:00 GMT");
header("cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("pragma: no-cache");

$oauth_consumer_key = "발급받은 컨슈머 키"; // Your consumer key
$oauth_consumer_key_secret = "발급받은 컨슈머 키 암호"; // Your consumer key secret

$oauth_callback = "콜백URL/callback.php";// Your Call Back Page URL

$oauth_signature_method = "HMAC-SHA1";
$oauth_timestamp = time();
$oauth_nonce = md5(microtime().mt_rand()); // md5s look nicer than numbers;
$oauth_version = "1.0";

$get_request_token_url = "https://oauth.nate.com/OAuth/GetRequestToken/V1a";

$oauth_token = "";
$oauth_token_secret = "";
$oauth_signature = "";

$request_token = "";
$request_token_secret = "";

//Get Request Token

//Generate Base String For Get Request Token
//!!파라메터 이름 순서로 조합해야 한다.
//!!파라메터의 이름과 값은 rfc3986 으로 encode
//[Name=Valeu&Name=Value…] 형식으로 연결
$Query_String = urlencode_rfc3986("oauth_callback")."=".urlencode_rfc3986($oauth_callback);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_consumer_key")."=".urlencode_rfc3986($oauth_consumer_key);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_nonce")."=".urlencode_rfc3986($oauth_nonce);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_signature_method")."=".urlencode_rfc3986($oauth_signature_method);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_timestamp")."=".urlencode_rfc3986($oauth_timestamp);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_version")."=".urlencode_rfc3986($oauth_version);

//Base String 요소들을 rfc3986 으로 encode
$Base_String = urlencode_rfc3986("POST")."&".urlencode_rfc3986($get_request_token_url)."&".urlencode_rfc3986($Query_String);

//지금 단계에서는 $oauth_token_secret이 ""
$Key_For_Signing = urlencode_rfc3986($oauth_consumer_key_secret)."&".urlencode_rfc3986($oauth_token_secret);

//oauth_signature 생성
$oauth_signature=base64_encode(hash_hmac('sha1', $Base_String, $Key_For_Signing, true));

//Authorization Header 조합
$Authorization_Header = "Authorization: OAuth ";
$Authorization_Header .= urlencode_rfc3986("oauth_version")."=\"".urlencode_rfc3986($oauth_version)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_nonce")."=\"".urlencode_rfc3986($oauth_nonce)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_timestamp")."=\"".urlencode_rfc3986($oauth_timestamp)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_consumer_key")."=\"".urlencode_rfc3986($oauth_consumer_key)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_callback")."=\"".urlencode_rfc3986($oauth_callback)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_signature_method")."=\"".urlencode_rfc3986($oauth_signature_method)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_signature")."=\"".urlencode_rfc3986($oauth_signature)."\"";

$parsed = parse_url($get_request_token_url);
$scheme = $parsed["scheme"];
$path = $parsed["path"];
$ip = $parsed["host"];
$port = @$parsed["port"];

if ($scheme == "http") {
if(!isset($parsed["port"])) { $port = "80"; } else { $port = $parsed["port"]; };
$tip = $ip;
} else if ($scheme == "https") {
if(!isset($parsed["port"])) { $port = "443"; } else { $port = $parsed["port"]; };
$tip = "ssl://" . $ip;
}
$timeout = 5;
$error = null;
$errstr = null;

//Request 만들기
$out = "POST " . $path . " HTTP/1.1\r\n";
$out .= "Host: ". $ip . "\r\n";
$out .= $Authorization_Header . "\r\n";
$out .= "Accept-Language: ko\r\n";
$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
$out .= "Content-Length: 0\r\n\r\n"; //Request Token 받기에서는 post body에 들어가는 파라메터가 없어서 0

//Request 보내기
$fp = fsockopen($tip, $port, $errno, $errstr, $timeout);

//Reponse 받기
if (!$fp) {
Message("연동중 API오류가 발생하였습니다. 다시 시도해주세요.", "close");
} else {
fwrite($fp, $out);
$response = "";
while ($s = fread($fp, 4096)) {
$response .= $s;
}

//Response Header와 Body 분리
$bi = strpos($response, "\r\n\r\n");
$body = substr($response, $bi+4);

//정상적인 경우 $body값은
//oauth_token=5a3377a10ad1f2c937e7bd8c83e57bec&oauth_token_secret=5be6580cc3e8ea2c71a1c56106c19c1f&oauth_callback_ctrue
//의 형식으로 떨어짐.
$tmpArray = explode("&",$body);
$TokenArray = explode("=",$tmpArray[0]);
$TokenSCArray = explode("=",$tmpArray[1]);
$request_token = $TokenArray[1];
$request_token_secret = $TokenSCArray[1];


//request_token, request_token_secret 세션에 저장
$_SESSION['oauth_request_token'] = trim($request_token);
$_SESSION['oauth_request_token_secret'] = trim($request_token_secret);
}

//Redirect to Authorize URL
//다음 단계인 Nate Login을 위해 페이지 이동
$Authorize_URL = "https://oauth.nate.com/OAuth/Authorize/V1a?oauth_token=".$request_token;
Header("Location: $Authorize_URL");

function urlencode_rfc3986($input) {
if (is_scalar($input)) {
return str_replace(
'+',
' ',
str_replace('%7E', '~', rawurlencode($input))
);
} else {
return '';
}
}
?>

-------------------------

callback.php

-------------------------

<?php
header("expires: Thu, 19 Nov 1981 08:52:00 GMT");
header("cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("pragma: no-cache");

include_once $g_Path_System . "/@inc/xml_parser_php5.php";

$oauth_consumer_key = "발급받은 컨슈머 키"; // Your consumer key
$oauth_consumer_key_secret = "발급받은 컨슈머 키 암호"; // Your consumer key secret

$oauth_callback = "콜백URL/callback.php";// Your Call Back Page URL

$callBackToken = $_REQUEST["oauth_token"];
$oauth_verifier= $_REQUEST["oauth_verifier"];

$request_token = $callBackToken;
$request_token_secret = "";

// 저장된 세션토큰과 전달받은 토큰 유효성 검사
$oauth_request_token = trim($_SESSION['oauth_request_token']);
$oauth_request_token_secret = trim($_SESSION['oauth_request_token_secret']);

if($oauth_request_token == $request_token && $oauth_request_token_secret != "") {
$request_token_secret = $oauth_request_token_secret;
} else {
Message("연동중 API오류가 발생하였습니다. 다시 시도해주세요.", "close");
}

//미리 request_token,request_token_secret를 저장 해 두었으로 매치되는 request_token_secret를 확보
$oauth_signature_method = "HMAC-SHA1";
$oauth_timestamp = time();
$oauth_nonce = md5(microtime().mt_rand()); // md5s look nicer than numbers;
$oauth_version = "1.0";

$get_access_token_url = "https://oauth.nate.com/OAuth/GetAccessToken/V1a";
$access_token = "";
$access_token_secret = "";

//Get Access Token

//Generate Base String For Get Access Token
//!!파라메터 이름 순서로 조합해야 한다.
//!!파라메터의 이름과 값은 rfc3986 으로 encode
//[Name=Valeu&Name=Value…] 형식으로 연결

$Query_String = urlencode_rfc3986("oauth_consumer_key")."=".urlencode_rfc3986($oauth_consumer_key);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_nonce")."=".urlencode_rfc3986($oauth_nonce);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_signature_method")."=".urlencode_rfc3986($oauth_signature_method);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_timestamp")."=".urlencode_rfc3986($oauth_timestamp);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_token")."=".urlencode_rfc3986($request_token);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_verifier")."=".urlencode_rfc3986($oauth_verifier);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_version")."=".urlencode_rfc3986($oauth_version);

//Base String 요소들을 rfc3986 으로 encode
$Base_String = urlencode_rfc3986("POST")."&".urlencode_rfc3986($get_access_token_url)."&".urlencode_rfc3986($Query_String);

//지금 단계에서는 $oauth_token_secret에 request_token_secret을 사용
$Key_For_Signing = urlencode_rfc3986($oauth_consumer_key_secret)."&".urlencode_rfc3986($request_token_secret);

//oauth_signature 생성
$oauth_signature = base64_encode(hash_hmac('sha1', $Base_String, $Key_For_Signing, true));

//Authorization Header 조합
$Authorization_Header = "Authorization: OAuth ";
$Authorization_Header .= urlencode_rfc3986("oauth_version")."=\"".urlencode_rfc3986($oauth_version)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_nonce")."=\"".urlencode_rfc3986($oauth_nonce)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_timestamp")."=\"".urlencode_rfc3986($oauth_timestamp)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_consumer_key")."=\"".urlencode_rfc3986($oauth_consumer_key)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_token")."=\"".urlencode_rfc3986($request_token)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_verifier")."=\"".urlencode_rfc3986($oauth_verifier)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_signature_method")."=\"".urlencode_rfc3986($oauth_signature_method)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_signature")."=\"".urlencode_rfc3986($oauth_signature)."\"";

$parsed = parse_url($get_access_token_url);
$scheme = $parsed["scheme"];
$path = $parsed["path"];
$ip = $parsed["host"];
$port = @$parsed["port"];

if ($scheme == "http") {
if(!isset($parsed["port"])) { $port = "80"; } else { $port = $parsed["port"]; };
$tip = $ip;
} else if ($scheme == "https") {
if(!isset($parsed["port"])) { $port = "443"; } else { $port = $parsed["port"]; };
$tip = "ssl://" . $ip;
}
$timeout = 5;
$error = null;
$errstr = null;

//Request 만들기
$out = "POST " . $path . " HTTP/1.1\r\n";
$out .= "Host: ". $ip . "\r\n";
$out .= $Authorization_Header . "\r\n";
$out .= "Accept-Language: ko\r\n";
$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
$out .= "Content-Length: 0\r\n\r\n"; //Request Token 받기에서는 post body에 들어가는 파라메터가 없어서 0

//Request 보내기
$fp = fsockopen($tip, $port, $errno, $errstr, $timeout);

//Reponse 받기
if (!$fp) {
Message("연동중 API오류가 발생하였습니다. 다시 시도해주세요.", "close");
} else {
fwrite($fp, $out);
$response = "";
while ($s = fread($fp, 4096)) {
$response .= $s;
}

//Response Header와 Body 분리
$bi = strpos($response, "\r\n\r\n");
$body = substr($response, $bi+4);

//정상적인 경우 $body값은
//oauth_token=d934cf945ee6f6bdfb65865f1c1d116a&oauth_token_secret=9a024ddded7a188790796bb9be32f4e5
//의 형식으로 떨어짐.
$tmpArray = explode("&",$body);
$TokenArray = explode("=",$tmpArray[0]);
$TokenSCArray = explode("=",$tmpArray[1]);
$access_token = $TokenArray[1];
$access_token_secret = $TokenSCArray[1];

//access_token, access_token_secret 출력
// echo ("access_token = ".$access_token."<br />");
// echo ("access_token_secret = ".$access_token_secret."<br />");

/* If HTTP response is 200 continue otherwise send to connect page to retry */
if ($access_token != "" && $access_token_secret != "") {
/* The user has been verified and the access tokens can be saved for future use */

// C로그 사용자 정보 불러오기 ---------------------------------------------------------------
$oauth_timestamp = time();
$oauth_nonce = md5(microtime().mt_rand()); // md5s look nicer than numbers;

$get_clog_user_info_url = "https://openapi.nate.com/OApi/RestApiSSL/CY/200800/gethomeinfo/v1";

$menuType="1";

//조회대상 미니홈피 아이디는 일촌 API로 확보 가능합니다.
$targetId="";//공백으로 두면 Access Token 소유자의 미니 홈피를 조회합니다.

//Generate Base String For Get Access Token
//!!파라메터 이름 순서로 조합해야 한다.
//!!파라메터의 이름과 값은 rfc3986 으로 encode
//[Name=Valeu&Name=Value…] 형식으로 연결

$Query_String = urlencode_rfc3986("oauth_consumer_key")."=".urlencode_rfc3986($oauth_consumer_key);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_nonce")."=".urlencode_rfc3986($oauth_nonce);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_signature_method")."=".urlencode_rfc3986($oauth_signature_method);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_timestamp")."=".urlencode_rfc3986($oauth_timestamp);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_token")."=".urlencode_rfc3986($access_token);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("oauth_version")."=".urlencode_rfc3986($oauth_version);
$Query_String .= "&";
$Query_String .= urlencode_rfc3986("targetId")."=".urlencode_rfc3986($targetId);

//Base String 구성 요소를 &로 연결
$Base_String = urlencode_rfc3986("POST")."&".urlencode_rfc3986($get_clog_user_info_url)."&".urlencode_rfc3986($Query_String);

//지금 단계에서는 $oauth_token_secret에 request_token_secret을 사용
$Key_For_Signing = urlencode_rfc3986($oauth_consumer_key_secret)."&".urlencode_rfc3986($access_token_secret);

//oauth_signature 생성
$oauth_signature=base64_encode(hash_hmac('sha1', $Base_String, $Key_For_Signing, true));

//Authorization Header 조합
$Authorization_Header = "Authorization: OAuth ";
$Authorization_Header .= urlencode_rfc3986("oauth_version")."=\"".urlencode_rfc3986($oauth_version)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_nonce")."=\"".urlencode_rfc3986($oauth_nonce)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_timestamp")."=\"".urlencode_rfc3986($oauth_timestamp)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_consumer_key")."=\"".urlencode_rfc3986($oauth_consumer_key)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_token")."=\"".urlencode_rfc3986($access_token)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_signature_method")."=\"".urlencode_rfc3986($oauth_signature_method)."\",";
$Authorization_Header .= urlencode_rfc3986("oauth_signature")."=\"".urlencode_rfc3986($oauth_signature)."\"";

$parsed = parse_url($get_clog_user_info_url);
$scheme = $parsed["scheme"];
$path = $parsed["path"];
$ip = $parsed["host"];
$port = @$parsed["port"];

$queryStr="targetId=".$targetId;
$queryLength = (strlen($queryStr));

if ($scheme == "http") {
if(!isset($parsed["port"])) { $port = "80"; } else { $port = $parsed["port"]; };
$tip = $ip;
} else if ($scheme == "https") {
if(!isset($parsed["port"])) { $port = "443"; } else { $port = $parsed["port"]; };
$tip = "ssl://" . $ip;
}
$timeout = 5;
$error = null;
$errstr = null;

//Request 만들기
$out = "POST " . $path . " HTTP/1.1\r\n";
$out .= "Host: ". $ip . "\r\n";
$out .= $Authorization_Header . "\r\n";
$out .= "Accept-Language: ko\r\n";
$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
$out .= "Content-Length: " . $queryLength . "\r\n\r\n";
$out .= $queryStr;

//echo("Request=".$out."<br />");
//exit;
//Request 보내기
$fp = fsockopen($tip, $port, $errno, $errstr, $timeout);

//Reponse 받기
if (!$fp) {
Message("연동중 API오류가 발생하였습니다. 다시 시도해주세요.", "close");
} else {
fwrite($fp, $out);
$response = "";
while ($s = fread($fp, 4096)) {
$response .= $s;
}

//echo("resp".$response."<br />");
//exit;

//Response Header와 Body 분리
$bi = strpos($response, "\r\n\r\n");
$body = substr($response, $bi+4);

$parser = new XMLParser($body); // 객체생성 parser라는 객체를 생성함
$parser->Parse(); // Parse()메소를 호출하여 xml을 dom 방식으로 파싱함

$rcode = $parser->document->rcode[0]->tagData;
$rmsg = $parser->document->rmsg[0]->tagData;

if($rcode == "RET0000") {
$nickname = $parser->document->name[0]->tagData;
$url_name = $parser->document->id[0]->tagData;
$profile_img_url_tmp = explode("<profileUrl><![CDATA[", $body);
$profile_img_url_tmp2 = explode("]]></profileUrl>", $profile_img_url_tmp[1]);
$profile_img_url = $profile_img_url_tmp2[0];

// 넘어온 인증정보를 통해 서버에 로그인 인증정보를 심기!

// 자체 프로그램 소스처리(DB를 저장하든, 세션으로 저장하든)

// ......

// ---------------------------------------------------

} else {
switch($rcode) {
case "RET0002" :
case "RET301" :
Message("싸이월드 \'ⓒ로그\'가 개설되어있지 않습니다. \\n 개설 후 이용하실 수 있습니다.", "close");
break;
default :
Message("[ {$rcode} / {$rmsg} ]\\n SNS로그인 연동을 진행할 수 없습니다. \\n 연동을 위해 싸이월드 \'ⓒ로그\'가 개설되어 있어야 합니다.", "close");
break;
}
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta c"text/html; charset=utf-8" http-equiv="Content-Type" />
</head>
<body>
<script>
opener.location.reload();
self.close();
</script>
</body>
</html>
<?
} else {
/* Save HTTP status for error dialog on connnect page.*/
Message("연동중 API오류가 발생하였습니다. 다시 시도해주세요.", "close");
}
}

function urlencode_rfc3986($input) {
if (is_scalar($input)) {
return str_replace(
'+',
' ',
str_replace('%7E', '~', rawurlencode($input))
);
} else {
return '';
}
}
?>

저작자 표시 비영리 변경 금지

Trackback 0 Comment 0
2011/11/17 18:33

[소셜(SNS)댓글] 네이버 미투데이(me2day) 연동 FAQ

크리에이티브 커먼즈 라이선스
Creative Commons License

--------------------------------------------------------------------------------------------------------

요즘 소셜(SNS)댓글 시스템이 커뮤니티 사이트에서 관심을 받고 있습니다.

이전에 IT관련 회사들은 어떻게 하면 회원가입률을 높일까를 고민하다 이제는 어떻게 하면 커뮤니티를 활성화 시킬 수 있을까로 고민이 바뀌고 있죠. 말 그대로 좋은 정보를 제공하는 것도 중요하지만, 방문자의 호응을 쉽게 이끌어내기 위한 노력으로 SNS 댓글시스템이 각광을 받고 있지 않나 싶습니다.

각 SNS(트위터, 페이스북, 미투데이, 요즘 등) 서비스들의 로그인 API연동에 대한 FAQ를 정리해보도록 하겠습니다.

개발하실 분들은 참조해서 도움이 되셨으면 좋겠습니다.

--------------------------------------------------------------------------------------------------------

네이버 미투데이는 OAuth를 사용치 않고 자체 간편인증을 사용합니다.

일단 애플리케이션 키 요청 http://me2day.net/me2/app/get_appkey

- 키값발급 및 callback 설정

프로그램으로

------

$akey = "발급받은 키값";

http://me2day.net/api/get_auth_url.xml?akey=".$akey

------

의 형태로 값을 전달하면 로그인 인증창의 URL을 토큰키와 같이 돌려줍니다.

돌려받은 url로 리다이렉트 시킨 후 토큰과 결과, 사용자 정보를 callback 에서 검사후 사용하면 완료~

-----------------

index.php

-----------------

<?php
header("expires: Thu, 19 Nov 1981 08:52:00 GMT");
header("cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("pragma: no-cache");

$akey = '발급받은 앱키";
$callback_url = '콜백URL/callback.php';

$response = http("http://me2day.net/api/get_auth_url.xml?akey=".$akey);
$get_url_tmp = explode("<url>", $response);
$get_url_tmp2 = $get_url_tmp[1];
$get_url_tmp3 = explode("</url>", $get_url_tmp2);
$url = $get_url_tmp3[0];

header('Location:'.$url);

function http($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
curl_close ($ch);
return $response;
}

?>

--------------------

callback.php

--------------------

<?php
header("expires: Thu, 19 Nov 1981 08:52:00 GMT");
header("cache-control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("pragma: no-cache");

include_once $g_Path_System . "/@inc/xml_parser_php5.php";

/**
* @file
* Take the user when they return from Twitter. Get access tokens.
* Verify credentials and redirect to based on response from Twitter.
*/

/* Start session and load lib */

$auth_token = ifilter($_REQUEST['token'], "STRING", 100);
$auth_result = ifilter($_REQUEST['result'], "STRING", 20);
$auth_user_id = ifilter($_REQUEST['user_id'], "STRING", 50);
$auth_user_key = ifilter($_REQUEST['user_key'], "STRING", 50);

$response = http("http://me2day.net/api/get_person/".$auth_user_id);

$parser = new XMLParser($response); // 객체생성 parser라는 객체를 생성함
$parser->Parse(); // Parse()메소를 호출하여 xml을 dom 방식으로 파싱함

$nickname = $parser->document->nickname[0]->tagData;
$profile_img_url = $parser->document->face[0]->tagData;

if(isset($auth_token) && isset($auth_result) && $auth_result == "true") {

/* The user has been verified and the access tokens can be saved for future use */

// 넘어온 인증정보를 통해 서버에 로그인 인증정보를 심기!

// 자체 프로그램 소스처리(DB를 저장하든, 세션으로 저장하든)

// ......

// ---------------------------------------------------

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta c"text/html; charset=utf-8" http-equiv="Content-Type" />
</head>
<body>
<script>
opener.location.reload();
self.close();
</script>
</body>
</html>
<?
} else {
/* Save HTTP status for error dialog on connnect page.*/
// header('Location: ./clearsessions.php');
Message("연동중 API오류가 발생하였습니다. 다시 시도해주세요.", "close");
}

function http($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
curl_close ($ch);
return $response;
}
?>

저작자 표시 비영리 변경 금지

Trackback 0 Comment 0
2011/11/17 18:32

[소셜(SNS)댓글] twitter 연동 FAQ

크리에이티브 커먼즈 라이선스
Creative Commons License

--------------------------------------------------------------------------------------------------------

요즘 소셜(SNS)댓글 시스템이 커뮤니티 사이트에서 관심을 받고 있습니다.

이전에 IT관련 회사들은 어떻게 하면 회원가입률을 높일까를 고민하다 이제는 어떻게 하면 커뮤니티를 활성화 시킬 수 있을까로 고민이 바뀌고 있죠. 말 그대로 좋은 정보를 제공하는 것도 중요하지만, 방문자의 호응을 쉽게 이끌어내기 위한 노력으로 SNS 댓글시스템이 각광을 받고 있지 않나 싶습니다.

각 SNS(트위터, 페이스북, 미투데이, 요즘 등) 서비스들의 로그인 API연동에 대한 FAQ를 정리해보도록 하겠습니다.

개발하실 분들은 참조해서 도움이 되셨으면 좋겠습니다.

--------------------------------------------------------------------------------------------------------

https://dev.twitter.com/ 개발계정 등록

- 어플리케이션을 등록

- Consumer key와 Consumer secret 발급

https://github.com/abraham/twitteroauth (curl 함수 필요)

다운로드 후 서버경로에 설치 후

config.php 파일 재설정 후 connect.php 실행

참고 사이트

https://dev.twitter.com/docs/auth/oauth

http://www.slideshare.net/episod/linkedin-oauth-zero-to-hero

http://ko.wikipedia.org/wiki/OAuth

저작자 표시 비영리 변경 금지

Trackback 0 Comment 0
2011/11/17 18:32

[소셜(SNS)댓글] 다음 요즘(yozm) 연동 FAQ

크리에이티브 커먼즈 라이선스
Creative Commons License

--------------------------------------------------------------------------------------------------------

요즘 소셜(SNS)댓글 시스템이 커뮤니티 사이트에서 관심을 받고 있습니다.

이전에 IT관련 회사들은 어떻게 하면 회원가입률을 높일까를 고민하다 이제는 어떻게 하면 커뮤니티를 활성화 시킬 수 있을까로 고민이 바뀌고 있죠. 말 그대로 좋은 정보를 제공하는 것도 중요하지만, 방문자의 호응을 쉽게 이끌어내기 위한 노력으로 SNS 댓글시스템이 각광을 받고 있지 않나 싶습니다.

각 SNS(트위터, 페이스북, 미투데이, 요즘 등) 서비스들의 로그인 API연동에 대한 FAQ를 정리해보도록 하겠습니다.

개발하실 분들은 참조해서 도움이 되셨으면 좋겠습니다.

--------------------------------------------------------------------------------------------------------

다음의 경우 OAuth 를 지원하기때문에 작업이 용이합니다.

Daum OAuth Library for PHP
http://github.com/azki/Daum-OAuth

해당 라이브러리를 다운받아 API인증을 받은 후 이용해서 callback 부분만 수정해서 사용하면 됩니다.

저작자 표시 비영리 변경 금지

Trackback 0 Comment 1
  1. Favicon of http://www.celinebagss.com BlogIcon Celine Bag 2012/05/22 17:36 address edit & del reply

    다음의 경우 OAuth 를 지원하기때문에 작업이 용이합니다.

    Daum OAuth Library for PHP
    http://github.com/azki/Daum-OAuth

    해당 라이브러리를 다운받아 API인증을 받은 후 이용해서 callback 부분만 수정해서 사용하면 됩니다.

2011/11/17 18:31

[소셜(SNS)댓글] facebook 연동 FAQ #2 - file_get_contents() 함수문제

크리에이티브 커먼즈 라이선스
Creative Commons License

--------------------------------------------------------------------------------------------------------

요즘 소셜(SNS)댓글 시스템이 커뮤니티 사이트에서 관심을 받고 있습니다.

이전에 IT관련 회사들은 어떻게 하면 회원가입률을 높일까를 고민하다 이제는 어떻게 하면 커뮤니티를 활성화 시킬 수 있을까로 고민이 바뀌고 있죠. 말 그대로 좋은 정보를 제공하는 것도 중요하지만, 방문자의 호응을 쉽게 이끌어내기 위한 노력으로 SNS 댓글시스템이 각광을 받고 있지 않나 싶습니다.

각 SNS(트위터, 페이스북, 미투데이, 요즘 등) 서비스들의 로그인 API연동에 대한 FAQ를 정리해보도록 하겠습니다.

개발하실 분들은 참조해서 도움이 되셨으면 좋겠습니다.

--------------------------------------------------------------------------------------------------------

페이스북 개발자 계정신청하고 기본 api 호출문으로 호출시 발생되는 상황대처법이다.

file_get_contents() 함수문제

[ 아래는 facebook 에서 제공하는 기본 api호출문 알리고리즘 ]

<?php

$app_id = "YOUR_APP_ID";
$app_secret = "YOUR_APP_SECRET";
$my_url = "YOUR_URL";

session_start();
$code = $_REQUEST["code"];

if(empty($code)) {
$_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
$dialog_url = "https://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
. $_SESSION['state'];

echo("<script> top.location.href='" . $dialog_url . "'</script>");
}

if($_REQUEST['state'] == $_SESSION['state']) {
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
. "&client_secret=" . $app_secret . "&code=" . $code;

$response = file_get_contents($token_url); // <--- file_get_contents 이 함수
$params = null;
parse_str($response, $params);

$graph_url = "https://graph.facebook.com/me?access_token="
. $params['access_token'];

$user = json_decode(file_get_contents($graph_url));
echo("Hello " . $user->name);
}
else {
echo("The state does not match. You may be a victim of CSRF.");
}

?>

Warning:
file_get_contents(
https://graph.facebook.com/oauth/access_token?client_id=163002433768527&redirect_uri=http%3A%2F%2F211.242.255.46%3A81%2FAdmin%2FFtc_Manager%2FNew_Board%2Fview.php%3Fno%3D22%26cpage%3D1&client_secret=05f3f6baa5f3f5fa0985ea0d860cce53&code=Y4pqWCC_7Zsremr_dSHu7dzIWbfXBL91SnHDR4OvXVo.eyJpdiI6Im4tN2NfWnhNSGpGSlFXakNRSlp2RXcifQ.q26b7Al9E1PJWXlK02IzU0A7oTbQNduqUNXna6Ve7U5JCDxPnlSAY21c0GYDMQY_glFHu-rTw_PfqMHtr_SjkxxA8TLoIM35CZYtN2C_dvSSoTwJ1LjyJQGZ-eBtzAIl) [function.file-get-contents]:

file_get_contents 함수의 경우 보안상 서버설정에서 차단하는 경우가 많은데

이때는 하나의 기능을 위해 해당 함수를 풀지말고

socket 이나 curl 을 이용해 대처하면 된다.

<?

function http($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$response = curl_exec($ch);
curl_close ($ch);
return $response;
}

?>

위와같은 펑션을 추가하고 file_get_contents를 http()함수로 교체하면 해결~!

저작자 표시 비영리 변경 금지

Trackback 0 Comment 0
2011/11/17 18:30

[소셜(SNS)댓글] facebook 연동 FAQ #1 - 페이스북 API 키 발급

크리에이티브 커먼즈 라이선스
Creative Commons License

--------------------------------------------------------------------------------------------------------

요즘 소셜(SNS)댓글 시스템이 커뮤니티 사이트에서 관심을 받고 있습니다.

이전에 IT관련 회사들은 어떻게 하면 회원가입률을 높일까를 고민하다 이제는 어떻게 하면 커뮤니티를 활성화 시킬 수 있을까로 고민이 바뀌고 있죠. 말 그대로 좋은 정보를 제공하는 것도 중요하지만, 방문자의 호응을 쉽게 이끌어내기 위한 노력으로 SNS 댓글시스템이 각광을 받고 있지 않나 싶습니다.

각 SNS(트위터, 페이스북, 미투데이, 요즘 등) 서비스들의 로그인 API연동에 대한 FAQ를 정리해보도록 하겠습니다.

개발하실 분들은 참조해서 도움이 되셨으면 좋겠습니다.

--------------------------------------------------------------------------------------------------------

이 문제로 약 1주일 가량 삽질을 했었습니다. 내용인 즉 정상적인 페이스북 계정을 개설하고, 친구추가와 포스팅을 2주가량 해오던 극히 정상적인 계정으로 개발자 센터에서 API 키를 발급신청했다.

돌아오는 메세지는...

------------------

You can no longer create apps because our systems indicated that your account may not be authentic. Facebook requires users to provide their real first and last names, and fake accounts are a violation of our Statement of Rights and Responsibilities (SRR 4.1), even when used to host or test apps. Also note that maintaining multiple accounts, even if they are authentic, is also prohibited. If you would like to create a test user to test app functionality, you can do so here: http://developers.facebook.com/docs/test_users/.
--------------------

가짜계정으로 의심되므로 테스트를 위해서는 테스트유저 계정을 이용하라는...

또 글을 쓰고 페이스북 활동을 하고 다시 신청해도 마찬가지...

대다수의 개발자 계정 신청시 아무런 문제가 없지만 구글링 해 본 결과 극히 일부에서만 벌어지는 현상이다.

일부 답변중 계정정보에 실명을 사용하라, 핸드폰 인증을 받아라....고 되어 있지만 그렇게 해도 해결되지 않는다...

해결방법: ISP - IP대역을 바꾸어 신청하면 깔끔하게 해결된다.

회사에서 사용하는 IP대역 2개로 해결되지 않아서, 새벽에 혹시나 집에있는 PC로 신청하니... 한방에 해결됨. --;

이 문제로 골치아픈 개발자들은 한번 시도해 보시길 바랍니다.

저작자 표시 비영리 변경 금지

Trackback 0 Comment 0
2011/09/27 15:43

[jQuery] 가시영역의 이미지만 로딩 - Lazy Load Plugin for jQuery (특정영역에만 적용가능)

크리에이티브 커먼즈 라이선스
Creative Commons License

요즘 유명 메이져사이트를 방문해보면 페이지 로딩 속도가 상당히 빨라졌다는 느낌이 들때가 있습니다.

방문자가 늘어난다고 서버시스템의 사양을 계속해서 높이거나 서버를 분산하기보다는
최대한 효율적인 방법으로 서버의 부하를 줄이는 노력을 강구해야 하는데 그중 이미지 파일들을 페이지 호출시 무작정 보여주는 것이 아니라 브라우져의 가시영역을 이동(스크롤)할 경우에만 해당 영역의 이미지를 보여주는 기능이 있어 소개합니다.
이렇게 함으로써 불필요한 서버의 로드를 줄일 수 있게 되어 서버의 성능에 좋은 영향을 미치게 됩니다.

방법론적인 차이는 있겠지만, 옥션이나 이미지를 주로 다루는 사이트들에서 많이 사용하는 방법이지요~!



이미지를 보시는 바와 같이 스크롤을 내리면 화면이 가시영역으로 들어오게되고,

이때 이미지를 서버에서 호출하게됩니다. 방문자가 많은 사이트나 이미지를 많이 사용하는 사이트에서

유용하게 사용할 수 있는 기능이 되겠네요.

사용법을 간단하게 안내해 드립니다.

1. 헤더부분에 아래코드를 넣음 
<script src="jquery.js" type="text/javascript"></script>
<script src="jquery.lazyload.js" type="text/javascript"></script>

2. 이미지 태그를 지정함 (기본코드)
$("img").lazyload();

3. 실제 적용예제(img/grey.gif 파일을 이미지 로드전에 보여줌)
<script type="text/javascript" charset="utf-8">
    $(function() {
        $("img").lazyload({placeholder : "img/grey.gif"});
    });
</script>


4. 특정영역에만 코드적용
게시판이나 본문내용외에 다른 이미지의 로드가 오작동하는 경우가 종종 발생합니다.
이를테면 전체 페이지 레이아웃을 DIV(CSS)로 구성하고 본문내용외의 오른쪽메뉴영역에 썸네일과 같은 이미지들이 있을 경우 페이지를 가장하단으로 가시영역을 스크롤하지 않으면 오른쪽이미지가 가시영역에 들어와있음에도 불구하고 로드되지 않는 경우가 발생합니다. (본문내용 영역이 하단으로 많이 내려올 경우에 종종 발생)

이때는 전체 페이지를 LazyLoad 효과를 적용하지 말고 특정 div 영역에만 국한되게 적용할 수 있습니다.
jQuery 문법인 $() 사용법과 마찬가지로 아래와 같이 적용합니다. 적용법은 아래와 같습니다.

<script type="text/javascript" charset="utf-8">
      $(function() {
          $("#lazyload img").lazyload({placeholder : "img/grey.gif"});
      });
</script>

<div id="lazyload">
.....<img src="....">
</div>

해당 "lazyload"라는 id값을 가진 div영역 내에서만 작동하게됩니다.



재밋게 활용해보세요.~! 특정영역 지정이나, 기타 옵션은 참고사이트 데모페이지를 참조하시기 바랍니다.
참고사이트: http://www.appelsiini.net/projects/lazyload/

저작자 표시 비영리 변경 금지

Trackback 0 Comment 0
2011/09/27 15:40

[Ajax] Microsoft.XMLHTTP(Ajax) - 서버 실시간 모니터링

크리에이티브 커먼즈 라이선스
Creative Commons License

2.0 시대를 시작하면서 ajax의 원리와 개념은 이제 널리 쓰이는 웹기술이 되었습니다.
이제 막 ajax의 활용법이나 개념을 배우시는 분들을 위해 아주 간단한 소스를 공개합니다.
해당 파일의 용도는 실시간으로 서버를 모니터링하는 소스이지만,

윈리를 분석하면 초단위로 특정위치의 정보를 특정페이지로 전달해주는 기능입니다.
이를 응용하게 되면 많은 곳에서 활용하실 수 있을겁니다.



서버의 특정 페이지에 올려주고, refresh_data.php 파일안의 DB 컨넥션 정보를 수정해 주시면,
바로 작동이 시작됩니다. 단, 해당 폴더에는 보안계정을 걸어주고 사용하시는 것이 안전할 것 같습니다.


저작자 표시 비영리 변경 금지

Trackback 0 Comment 1
  1. Favicon of http://www.celinebagss.com BlogIcon Celine Bag 2012/05/22 17:40 address edit & del reply

    Ajax, php, xmlhttp, 서버 모니터링, 실시간

2011/09/27 15:38

[MYSQL] mysql data type (DB 데이터 타입)

크리에이티브 커먼즈 라이선스
Creative Commons License

데이터베이스를 오래 다루다 보면 으레 많이 사용하는 데이터타입을 무의식중에 설계해서 사용하는 경우가 많습니다. 나중에 사이트가 개발이 완료되고 운영이 오래 지속되다 보면 DB의 튜닝이 필요하게 되는데 근본적으로 좀더 손이 덜가기 위해서는 만들때부터 설계를 잘하는게 '정도'일 것입니다.

잊혀지기 쉽지만 DB에서 가장 중요한 데이터 타입에 대해서 알아보도록 하겠습니다.

mysql, 오라클, ms-sql 모두 비슷한 데이터 타입을 사용하고 있으나, DBMS별로 조금씩 추가되거나 향상된 데이터 타입들이 있으니 참고해서 사용하기 바랍니다.

분류

데이터 타입

범위

저장소크기

정수 Bit 0 또는 1 bit
Int -2,147,483,648 ~ 2,147,483,647 4 바이트
Smallint -32,768 ~ 32,767 2 바이트
Tinyint 0 ~ 255 1 바이트
Bigint -2^63 ~ 2^63-1 8 바이트
부동소수점 Float[n] -1.79E+308 ~ 1.79E+308
n = 1~24
4 바이트
Float[n] -1.79E+308 ~ 1.79E+308
n = 25~53
8 바이트
Real -3.40E + 38 ~ 3.40E + 38 4 바이트
문자데이터 char[n] n = 1~8000 n 바이트
Varchar[n] n = 1~8000 입력한 데이터의 길이
Text 최대 2,147,483,647자의 가변길이
유니코드
문자데이터
Nchar n = 1~4000 n*2 바이트
nvarchar n = 1~4000 입력한 데이터의 길이*2 바이트
Ntext 최대 1,073,741,823자의 가변길이
이진데이터 binary n = 1~8000 n+4 바이트
varbinary n = 1~8000 입력한 데이터의 길이+4 바이트
Image 최대 2,147,483,647자의 가변길이
날짜와시간 datetime 1753/1/1~9999/12/31 8 바이트
smalldatetime 1900/1/1~2079/6/6 4 바이트
화폐 money -922,337,203,685,477.5808~ +922,337,203,685,477.5807 8 바이트
smallmoney -214,748.3648~214,748.3647 4 바이트
저작자 표시 비영리 변경 금지

Trackback 0 Comment 0