성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 그냥 RSS Reader 기능과 약간의 UI 편의성 때문에 사용...
[이종효] 오래된 소프트웨어는 보안 위협이 되기도 합니다. 혹시 어떤 기능...
[정성태] @Keystroke IEEE의 문서를 소개해 주시다니... +_...
[손민수 (Keystroke)] 괜히 듀얼채널 구성할 때 한번에 같은 제품 사라고 하는 것이 아...
[정성태] 전각(Full-width)/반각(Half-width) 기능을 토...
[정성태] Vector에 대한 내용은 없습니다. Vector가 닷넷 BCL...
[orion] 글 읽고 찾아보니 디자인 타임에는 InitializeCompon...
[orion] 연휴 전에 재현 프로젝트 올리자 생각해 놓고 여의치 않아서 못 ...
[정성태] 아래의 글에 정리했으니 참고하세요. C# - Typed D...
[정성태] 간단한 재현 프로젝트라도 있을까요? 저런 식으로 설명만 해...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <div style='font-family: 맑은 고딕, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>페이스북(Facebook) 계정으로 로그인하는 C# 웹 사이트 제작</div> <br /> 트위터 계정 연동을 알아보았는데요.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > 트위터 계정으로 로그인하는 C# 웹 사이트 제작 ; <a target='_tab' href='http://www.sysnet.pe.kr/2/0/948'>http://www.sysnet.pe.kr/2/0/948</a> </pre> <br /> 기왕 하는 거 ^^ 페이스북도 알아봐야 하지 않을까요?<br /> 어차피 모두 OAuth 인증 방식을 도입했기 때문에 접근 방법도 비슷해서 부담이 적습니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 지난 번처럼, 우선 .NET 용 라이브러리를 찾아야 할텐데요. 오픈 소스로 되어 있는 다음의 라이브러리가 Facebook에 의해서 링크되어 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > C# SDK for Facebook Platform ; <a target='_tab' href='https://github.com/facebook/csharp-sdk'>https://github.com/facebook/csharp-sdk</a> </pre> <br /> 소스 코드로만 공개되어 있기 때문에 번거롭지만 다운로드 받아서 빌드를 직접 해줘야 합니다. (FacebookAPI.dll)<br /> <br /> 그다음, 트위터와 마찬가지로 페이스북 역시 여러분들의 응용 프로그램을 등록해 줘야 합니다. 검색을 해보니, 아래의 사이트에서 잘 설명을 해주고 있습니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > SNS - 페이스북에 어플리케이션 올리기 ; <a target='_tab' href='http://sherlockpj.blog.me/70091818802'>http://sherlockpj.blog.me/70091818802</a> </pre> <br /> 위에서 일러준데로, <a target='_tab' href='http://www.facebook.com/developers'>http://www.facebook.com/developers</a> 링크로 이동해서 로그인을 하고, 아래의 허가 요청에 대해서 허용을 합니다. (특이하게도, 페이스북 내부의 개발자 설정 역시도 페이스북의 '외부 응용 프로그램'처럼 대우를 하는군요.)<br /> <br /> <img alt='integrate_facebook_auth_1.png' src='/SysWebRes/bbs/integrate_facebook_auth_1.png' /><br /> <br /> 다음으로, "새 어플리케이션 설정" 버튼을 누르고,<br /> <br /> <img onclick='toggle_img(this)' class='imgView' alt='integrate_facebook_auth_2.png' src='/SysWebRes/bbs/integrate_facebook_auth_2.png' /><br /> <br /> 응용 프로그램 이름을 입력하고, 생성!<br /> <br /> <img alt='integrate_facebook_auth_3.png' src='/SysWebRes/bbs/integrate_facebook_auth_3.png' /><br /> <br /> 이후의 과정은 각자 응용 프로그램 상황에 맞게 설정하고 확인을 누르면 완료.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 트위터의 경우에 "Consumer Key"와 "CustomerSecret"를 얻을 수 있었던 것처럼, 페이스북에서도 비슷한 값들을 "Application ID"와 "Application Secret"으로 제공하고 있습니다.<br /> <br /> 하지만, 인증 서비스에 있어 페이스북이 좀 더 다양한 기능들을 제공해 주고 있는데요. 개인적으로 마음에 드는 것이 SSO(Single-Sign-on) 기능과 "Deauthorize URL" 등록 기능입니다.<br /> <br /> 우선, ASP.NET에서의 SSO 구현은 다음의 웹 사이트에서 자세히 설명하고 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > Facebook Platform's OAuth 2.0 Protocol and ASP.NET MVC ; <a target='_tab' href='http://amirrajan.net/Blog/asp-mvc-and-facebook-single-sign-on'>http://amirrajan.net/Blog/asp-mvc-and-facebook-single-sign-on</a> </pre> <br /> 위와 같이 서버 측에서 제어하는 것도 가능한데요. 페이스북은 클라이언트의 JavaScript에서도 SSO 인증이 되도록 하는 js 파일을 공개해 주고 있습니다. 이에 대해서는 다음의 글에서 "Single Sign-on" 부분을 참고하실 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > Facebook for Websites - Single Sign-on ; <a target='_tab' href='http://developers.facebook.com/docs/guides/web'>http://developers.facebook.com/docs/guides/web</a> </pre> <br /> 위의 글에서 설명된 것처럼 SSO 구현은 여러분들의 웹 사이트에 다음과 같은 HTML 및 Javascript 링크와 코드를 추가해 주는 것으로 간단하게 적용될 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > <b style='COLOR: blue'><div id="fb-root"></div></b> <script src="http://connect.facebook.net/en_US/all.js"></script> <script> FB.init({appId: '[응용 프로그램 등록 시 받는 Application ID]', status: true, cookie: true, xfbml: true}); FB.Event.subscribe('<b style='COLOR: blue'>auth.sessionChange</b>', function(response) { if (response.session) { // 로그인 상태로 판정될 때 실행되는 코드 } else { // 로그아웃 상태로 판정될 때 실행되는 코드 } }); </script> <b style='COLOR: blue'><fb:login-button></fb:login-button> <!-- 로그인 버튼 이미지 --></b> </pre> <br /> <fb:login-button />으로 표시되는 로그인 버튼 이미지를 사용자가 클릭하면 페이스북 측에서 제공하는 로그인 화면이 팝업창으로 뜨고 사용자는 페이스북 로그인 하듯이 사용자 정보를 입력합니다. 물론, 웹 사이트 측에는 트위터에서 그랬던 것처럼 사용자 계정에 대해서는 어떠한 정보도 알려주지 않고 access_token 값 만을 넘겨주게 됩니다.<br /> <br /> FB.init / FB.Event.subscribe의 자바스크립트 역할은 간단합니다. 만약, 사용자가 Facebook 로그인에 대해서 "로그인 상태 유지(Remember Me)"를 체크해 놓고 로그인 한 적이 있다면, 위의 자바 스크립트 함수를 포함하는 웹 사이트를 방문하면 초기 FB... 메서드 실행 시에 페이스북 사이트로부터 정보를 조회해서 로그인 처리를 하게 됩니다. 반대로, 현재 로그인 해서 사용하고 있는 웹 사이트와는 별개의 창으로 떠 있는 웹 브라우저에서 방문중인 페이스북에서 로그아웃을 하는 경우에도, 위의 자바스크립트가 실행되면 '로그 아웃' 부분에 해당하는 자바 스크립트 코드가 실행될 수 있습니다.<br /> <br /> 인증처리를 서버측에서 하느냐, 자바스크립트로 하느냐에 대해서는 장단점이 있습니다. 자바스크립트를 활용하게 되면 서버 측에서 지저분하게 인증 관련 코드를 넣을 필요가 없어서 좋긴 하지만 대부분의 경우 다시 화면을 refresh 해주는 코드를 자바스크립트에 넣어주어서 화면 깜빡임이 발생하게 됩니다.<br /> <br /> SSO를 조금이라도 아시는 분들이라면, 그 방법이 쿠키임을 짐작하실 테고, 그렇다면 쿠키가 적용되는 도메인 영역이 지정되어야 할 텐데, 페이스북은 어떻게 이를 판단할까요? 네... 이 부분은 응용 프로그램 등록화면에서 쿠키가 적용될 도메인 영역을 다음과 같이 미리 지정해 주었어야 합니다.<br /> <br /> <img onclick='toggle_img(this)' class='imgView' alt='integrate_facebook_auth_4.png' src='/SysWebRes/bbs/integrate_facebook_auth_4.png' /><br /> <br /> 로그인 된 경우, 지정된 도메인 영역으로 다음과 같은 쿠키 설정이 추가됩니다.<br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; width: 700px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: 맑은 고딕, Consolas, Verdana; COLOR: #005555'> fbs_[AppId]="access_token=[AppId]...&base_domain=[사이트 도메인]&expires=...[인증유효기간]...&secret=....&session_key=....&sig=....&uid=...";<br /> </div><br /> <br /> 페이스북 로그인 연동이 적용된 제 웹 사이트의 경우에 풀어보면 다음과 같습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > fbs_[AppId]="...[이하 아래의 값들이 개행문자 없이 나열됨]..." <b style='COLOR: blue'>access_token</b>: ...[생략]... base_domain: <b style='COLOR: blue'>www.sysnet.pe.kr</b> expires: 1290085200 secret: ...[생략]... session_key: ...[생략]... sig: ...[생략]... uid: ...[생략]... name : SeongTae Jeong email: ...[생략]... website: http://www.sysnet.pe.kr </pre> <br /> 위의 정보에서 중요한 것은 "access_token" 값입니다. 그 값을 기반으로 이전에 빌드해 둔, FacebookAPI.dll을 이용하여 페이스북 웹 사이트로부터 제공되는 다양한 API를 접근하게 되는데, 이와 관련해서 자세한 개발 관련 정보는 아래의 웹 페이지에서 찾아볼 수 있습니다.<br /> <a name='graph_api'></a> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > Graph API Overview ; <a target='_tab' href='http://developers.facebook.com/docs/api'>http://developers.facebook.com/docs/api</a> Graph API Reference ; <a target='_tab' href='http://developers.facebook.com/docs/reference/api/'>http://developers.facebook.com/docs/reference/api/</a> </pre> <br /> 예를 들어, "사용자" 정보를 조회하고 싶다면, "Graph API Reference"에서 살펴보고 <a target='_tab' href='http://developers.facebook.com/docs/reference/api/user'>http://developers.facebook.com/docs/reference/api/user</a>에서 설명되고 있는 것임을 인식하고, 그 페이지에 제시된 쿼리 URL을 아래와 같이 찾을 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > User A user profile. This object supports Real-Time Updates for all properties except the verified property. 예 <b style='COLOR: blue'>https://graph.facebook.com/me</b> (current user) </pre> <br /> 도메인 까지의 쿼리 주소는 FacebookAPI에서 붙여주기 때문에 뒤의 "/me"만 붙여서 다음과 같이 조회를 해 올 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > Facebook.FacebookAPI api = new Facebook.FacebookAPI(...[쿠키에서 구해온 access_token 값]...); Facebook.JSONObject me = api.Get("/me"); </pre> <br /> 그런 후, 반환되는 것은 해당 명세서에 보이는 것 처럼 id, first_name,... 등등의 값을 다음과 같이 조회해 올 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > string userName = me.Dictionary["first_name"].String; string userId = me.Dictionary["id"].String; </pre> <br /> 여기까지 기본적인 인증 방법 및 사용법 설명은 끝입니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> 부가적으로, 더 설명드려야 하는 것이 있다면 "사용자 정보" 조회 등에 대해서 일부 정보는 반드시 사용자로부터의 허락을 받아야만 가져올 수 있다는 점입니다. (이 부분에 대해서는 페이스북 개발자에게 정말 박수를 쳐주고 싶습니다. ^^)<br /> <br /> 예를 들면, 위의 api.Get("/me"); 코드를 통해서 사용자 정보를 조회할 때 email을 조회하면 빈 문자열이 반환되는 것을 확인할 수 있습니다. 왜냐하면, email 정보는 "사용자"가 해당 응용 프로그램이 조회해도 좋다는 허락을 해줘야 하기 때문입니다.<br /> <br /> 이에 대해서는 "<a target='_tab' href='http://developers.facebook.com/docs/reference/api/user'>http://developers.facebook.com/docs/reference/api/user</a>"에서도 다음과 같이 명시되어 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > email : Requires <b style='COLOR: blue'>email</b> permission </pre> <br /> 만약, 여러분들의 웹 애플리케이션(또는 응용 프로그램)에서 사용자의 이메일 정보가 필요하다면 명시적으로 요청을 해야 합니다. 위에서 설명한 "<fb:login-button />" 버튼을 이용한 경우 다음과 같이 간단하게 처리가 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > <fb:login-button perms="...[요구되는 정보를 위한 권한 문자열]..."></fb:login-button> </pre> <br /> 제 웹 사이트의 경우 사용자 정보에서 "email"과 "user_website" 정보 2가지를 요구하기 때문에 다음과 같이 설정되어 있고,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > <fb:login-button perms="email,user_website"></fb:login-button> </pre> <br /> 사용자는 최초 페이스북 로그인 시에 다음과 같이 확인을 받게 됩니다.<br /> <br /> <img alt='integrate_facebook_auth_5.png' src='/SysWebRes/bbs/integrate_facebook_auth_5.png' /><br /> <br /> <hr style='width: 50%' /><br /> <br /> 더욱 훌륭한 것은, 이메일 정보의 보호입니다. 사실, 자신이 사용하려는 웹 사이트가 이메일 정보를 요구한다면 "줄 수밖에 없는 상황"이 되어버리는 데요. (누군들, 사이트 약관을 읽어보고 정보 제공에 동의하고 싶겠습니까?) 페이스북은 이메일 주소를 외부적으로 노출되는 전용 이메일 계정을 별도로 제공해주는 데요. 이름하여 "proxied email"입니다. (사용자는 페이스북의 계정 정보 설정에서 이런 경우 "proxied email" 주소를 제공할 것인지, 실제 이메일 주소를 제공할 것인지를 선택할 수가 잇습니다.)<br /> <br /> 그래서, 페이스북 이외의 다른 응용 프로그램들은 원래의 사용자 이메일 정보를 알 수는 없고 페이스북에서 중계해주는 "proxied email" 주소만을 알 수 있습니다. 이에 대해서는 다음의 글에서 자세히 설명해 주고 있으니 참고하세요. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > Facebook App Notifications Moving to Your E-mail Inbox ; <a target='_tab' href='http://mashable.com/2010/01/20/facebook-applications-email/'>http://mashable.com/2010/01/20/facebook-applications-email/</a> </pre> <br /> 사용자 정보 보호에 이런 세심함을 보여주는 웹 사이트를 보고 있노라니... 오히려 사용자 정보를 팔아먹는 못된 사이트들과 비교가 되는군요. ^^; <br /> <br /> <hr style='width: 50%' /><br /> <br /> 대부분의 외부 웹 응용 프로그램에서 취하는 형태가 바로 "페이스북 연동"일 것입니다. 기존 웹 애플리케이션 계정 정책에 페이스북 계정을 연동하기 위해서는 쿠키로부터 uid 값을 취해서 현재 "외부 웹 응용 프로그램"에 로그인한 사용자 계정과 연관지어 보관해 두어야 합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > access_token: ...[생략]... base_domain: www.sysnet.pe.kr expires: 1290085200 secret: ...[생략]... session_key: ...[생략]... sig: ...[생략]... <b style='COLOR: blue'>uid: 10302394932804</b> name : SeongTae Jeong email: ...[생략]... website: http://www.sysnet.pe.kr </pre> <br /> 이렇게 되면, 나중에는 페이스북 계정연동으로 인한 DB 자료들이 늘어나게 될 텐데요. 재미있는 점은, 사용자는 언제든지 아래에서 보는 것처럼 페이스북 웹 사이트로부터 여러분들의 웹 사이트와의 연동을 해제할 수 있다는 것입니다.<br /> <br /> <img alt='integrate_facebook_auth_6.png' src='/SysWebRes/bbs/integrate_facebook_auth_6.png' /><br /> <br /> 따라서 이런 상황이 되면 웹 사이트 DB 에는 더 이상 쓸모없는 페이스북 관련 연동 정보가 쌓여만 가는 상황이 되는 것입니다.<br /> <br /> 정상적이라면, 이런 경우 페이스북 측에서 "어플리케이션 제거" 링크를 사용자가 누를 때 해당 웹 사이트에 통지를 해주면 좋을 텐데요. 바로 이 기능을 위해서 응용 프로그램 설정 화면에서 "Deauthorize URL" 입력란이 있는 것입니다.<br /> <br /> <img onclick='toggle_img(this)' class='imgView' alt='integrate_facebook_auth_7.png' src='/SysWebRes/bbs/integrate_facebook_auth_7.png' /><br /> <br /> 위에서는 "/user/removeuser.aspx" 웹 페이지를 부르도록 하고 있는데요. 페이스북은 사용자가 "어플리케이션 제거" 링크를 누르면 "removeuser.aspx" 호출 시에 POST 데이터에 여러 가지 정보를 넣어주는 데 이 중에서 "fb_sig_user" 값이 인증 시에 쿠키에 담겨 있던 "uid" 값이 되므로 사용자 정보를 DB에서 정상적으로 제거해 줄 수 있게 됩니다. 대략 다음과 같은 서버 측 코드를 구성해주면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > public partial class removeuser : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { string userId = <b style='COLOR: blue'>Request.Form["fb_sig_user"];</b> if (string.IsNullOrEmpty(userId) == false) { ...[DB에서 제거]... } } } </pre> <br /> 물론... 하필 사용자가 "어플리케이션 제거"를 할 때 여러분들의 웹 서버가 멈춰있다면... 어쩔 수 없겠군요. ^^<br /> <br /><br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
6309
(왼쪽의 숫자를 입력해야 합니다.)