성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
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 연동 - API Error Description: Invalid OAuth 2.0 Access Token</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;' > 페이스북(Facebook) 계정으로 로그인하는 C# 웹 사이트 제작 ; <a target='_tab' href='http://www.sysnet.pe.kr/2/0/953'>http://www.sysnet.pe.kr/2/0/953</a> </pre> <br /> 테스트하다 보니 재미있는 현상이 하나 나왔습니다.<br /> <br /> <ol> <li>A 컴퓨터에서 "로그인 상태 유지"로 로그인</li> <li>B 컴퓨터에서 같은 계정으로 "로그인 상태 유지"로 로그인</li> <li>A, B 컴퓨터 모두 웹 브라우저 종료</li> <li>A 컴퓨터에서 "로그 아웃"</li> <li>B 컴퓨터에서 웹 브라우저를 띄우고 페이스북 계정 연동 사이트 방문</li> </ol> <br /> 위와 같이 하면, A 컴퓨터에서는 다시 로그인 과정을 밟아서 계정 연동이 되는 반면, B 컴퓨터에서는 기존에 남아 있던 "fbs_[AppId]" 쿠키 값으로 인해 '자동 로그인'이 시도되고 이미 A 컴퓨터에서 로그아웃을 해버려서 액세스 토큰이 유효하지 않게 되어 무조건 다음과 같은 오류 창으로 넘어가게 됩니다. (실제로 B 컴퓨터에는 "javascript:alert(document.cookie)"로 확인을 하면 이전의 쿠키값이 살아 있는 것을 볼 수 있습니다.)<br /> <br /> <img alt='fb_login_error_1.png' src='/SysWebRes/bbs/fb_login_error_1.png' /><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'> An error occurred with 성태의 닷넷 이야기. Please try again later.<br /> <br /> <b style='COLOR: blue'>API Error Code: 190<br /> API Error Description: Invalid OAuth 2.0 Access Token<br /> Error Message: Error validating access token.<br /> </b></div><br /> <br /> 아마도 같은 계정에 대해서 여러 대의 PC에서 로그인을 하는 것에 대해 페이스북 서버 측에서 "Acces Token"에 대한 정상적인 관리가 안되는 듯 싶습니다. <br /> <br /> 어떡할까? 고민하다가,,, 이런 문제를 방지하기 위해 로그인 시도를 할 때 기존에 설정된 "fbs_[App Id]" 쿠키 값을 지우고 로그인 창을 띄우는 식으로 방향을 잡았습니다. 이렇게 하려면 "<fb:login-button />"을 그냥 사용하는 것은 무리가 있었습니다.<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;' > <img style="cursor: pointer" <b style='COLOR: blue'>onclick="fb_Login()"</b> src="login-button.png" /> </pre> <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;' > <div id="fb-root"></div> <script language="javascript" type="text/javascript" src="http://connect.facebook.net/en_US/all.js"></script> <script language="javascript" type="text/javascript"> FB.init({ appId: [Your App ID], status: false, cookie: true, xfbml: true }); function fb_Login() { <b style='COLOR: blue'>document.cookie = "fbs_[Your App ID]=;"; // 쿠키를 제거해 주고,</b> <b style='COLOR: blue'>FB.login</b>(function (response) { // 페이스북 로그인 창을 띄웁니다. if (response.session) { // 로그인 상태로 판정될 때 실행되는 코드 } else { // 로그아웃 상태로 판정될 때 실행되는 코드 } }, <b style='COLOR: blue'>{ perms: 'email,user_website' }</b>); // fb:login-button의 perms 속성으로 지정된 값 나열 } </script> </pre> <br /> 아쉬운 점은, 쿠키값이 클라이언트에서 자바 스크립트로 해제되긴 하지만, 웬일인지 FB.login 버튼으로 실행되는 창에 곧바로 반영되지 않았습니다. 그래서 이렇게 클라이언트 측에서 처리를 하게 되면 반드시 한번의 redirection을 거쳐야만 한 번 더 로그인 시도를 했을 때 정상적으로 동작하게 되는 단점이 있습니다.<br /> <br /> 이런 상황을 좀 더 매끄럽게 해결하려면 서버 측에서 판단하는 코드를 넣어주어야 하는데요.<br /> 가만히 보니까, 위와 같이 "Invalid OAuth 2.0 Access Token" 상태의 fbs_ 쿠키값을 가지고 Facebook.FacebookAPI.Get 메서드를 호출하게 되면 다음과 같은 예외가 발생하였습니다.<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'>Server Error: Facebook.FacebookAPIException: The remote server returned an error: (400) Bad Request.</b> at Facebook.FacebookAPI.MakeRequest(Uri url, HttpVerb httpVerb, Dictionary`2 args) in D:\...\FacebookAPI.cs:line 194 at Facebook.FacebookAPI.Call(String relativePath, HttpVerb httpVerb, Dictionary`2 args) in D:\...\FacebookAPI.cs:line 132 at Facebook.FacebookAPI.Get(String relativePath) in D:\...\FacebookAPI.cs:line 69 at TestAPI.test.CheckFacebookLogin() in D:\...\test.ascx.cs:line 219 </pre> <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;' > try { me = api.Get("/me"); } catch (Facebook.FacebookAPIException fbEx) { if (Request.Cookies["fbs_" + ApplicationId] != null) { HttpCookie fbsCookie = new HttpCookie("fbs_" + ApplicationId); fbsCookie.Expires = DateTime.Now.AddDays(-1); Response.Cookies.Add(fbsCookie); } } </pre> <br /> 위와 같이 처리를 하게 되면, 실제로 페이스북 서버 문제로 "400 bad request"가 발생했을 때 조차도 로그 아웃이 되어버리는 (흔치 않는) 문제가 있겠지만, 그래도 클라이언트 측 스크립트에서의 두 번 재시도 로그인 처리보다는 나은 것 같습니다.<br /> <br /> 암튼, 페이스북 서버 측 코드를 알 수 없어 정확한 분석을 하기는 힘들지만, 일단은 위와 같이 처리를 해주니 현재는 문제없이 페이스북 로그인 계정 연동이 되고 있습니다. (어쨌든, 실제 적용하면서 느낀 건데, 페이스북의 SSO 기능이 그다지 매끄럽지는 않은 것 같습니다.)<br /> <br /> <br /> <br /><br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
7481
(왼쪽의 숫자를 입력해야 합니다.)