인증을 위해 Facebook을 사용하는 웹 사이트 용 REST API


86

우리는 사이트 에 로그인하고 자신을 인증 하는 유일한 방법이 Facebook을 사용하는 웹 사이트를 가지고 있습니다 (내 선택이 아님). Facebook으로 처음 로그인하면 계정이 자동으로 생성됩니다.

이제 우리 사이트를위한 iPhone 애플리케이션을 만들고 다른 사람들이 우리 서비스를 사용할 수 있도록 공용 API를 만들고 싶습니다.

이 질문은 앱 / API에서 웹 사이트를 인증하는 방법에 관한 것이며 두 부분으로 나뉩니다.

  1. API에서 Facebook OAuth 만 인증 방법으로 사용하는 웹 사이트로 REST 인증을 처리하는 올바른 방법은 무엇입니까?

REST API에 대한 표준 인증 방법을 읽고 연구했습니다. 사용자에 대한 자격 증명이 없기 때문에 HTTPS를 통한 기본 인증 과 같은 방법을 사용할 수 없습니다 . 이와 같은 것은 API를 사용하여 애플리케이션을 인증하기위한 것 같습니다.

현재 제가 생각할 수있는 가장 좋은 방법은 API의 / authorize 엔드 포인트에 도달하면 Facebook OAuth로 리디렉션 된 다음 사이트로 다시 리디렉션되고 API 사용자가 후속 인증에 사용할 수있는 '토큰'을 제공하는 것입니다. 요청.

  1. 우리가 만든 공식 애플리케이션의 경우 반드시 같은 방식으로 공용 API를 사용할 필요는 없습니다. 웹 사이트와 대화하고 사용자를 인증하는 가장 좋은 방법은 무엇입니까?

API (공개) 키와 비밀 (개인) 키를 사용하여 API를 사용하는 타사 애플리케이션을 인증하는 방법을 이해합니다. 그러나 앱을 사용하는 사용자를 인증 할 때 사용자를 인증해야하는 유일한 방법이 Facebook 일 때 어떻게해야할지 혼란스러워하고 있습니다.

매우 분명한 것을 놓치고 있거나 공개 REST API가 어떻게 작동해야하는지 완전히 이해하지 못하는 것 같으므로 조언과 도움을 주시면 대단히 감사하겠습니다.


비슷한 질문이 stackoverflow.com/questions/30230482/ 에 있습니다.이 중 일부에 대해 이야기합니다
JVK

답변:


99

업데이트 : 아래 참조

저도이 질문에 대해 열심히 생각하고 있습니다. 아직 완전히 명확하지는 않지만 여기에 제가 생각하고있는 경로가 있습니다. 내 사용자 가 Facebook 연결 로만 인증 하는 REST API를 만들고 있습니다.

클라이언트에서 :

  1. Facebook API를 사용하여 로그인하고 OAUTH2 코드를받습니다.
  2. 이 코드를 액세스 토큰으로 교환하십시오.
  3. 내 사용자 지정 API를 호출 할 때마다 Facebook 사용자 ID와 액세스 토큰을 포함합니다.

API에서 (사용자 인증이 필요한 모든 방법에 대해) :

  1. 위의 액세스 토큰을 사용하여 / me Facebook 그래프에 요청합니다.
  2. 반환 된 Facebook 사용자 ID가 위에서 내 API로 전달 된 사용자 ID와 일치하는지 확인합니다.
  3. 액세스 토큰이 만료 된 경우 추가 통신이 필요합니다.

아직 테스트하지 않았습니다. 어떻게 들리나요?

--- 업데이트 : 2014 년 7 월 27 일 질문에 답하기 위해 ---

위의 교환은 로그인시 한 번만 사용합니다. 어떤 사용자가 로그인하고 있는지 확인한 후 고유 한 액세스 토큰을 만들고 해당 토큰은 앞으로 그 시점부터 사용됩니다. 새 흐름은 다음과 같습니다.

클라이언트에서 :

  1. Facebook API를 사용하여 로그인하고 OAUTH2 코드를받습니다.
  2. 이 코드를 액세스 토큰으로 교환하십시오.
  3. Facebook 토큰을 매개 변수로 포함하여 API 에서 액세스 토큰 요청

API에서

  1. 액세스 토큰 요청을받습니다.
  2. facebook 액세스 토큰을 사용하여 / me Facebook 그래프에 요청합니다.
  3. Facebook 사용자가 존재하고 내 데이터베이스의 사용자와 일치하는지 확인
  4. 나만의 액세스 토큰을 만들고 저장 한 다음이 시점부터 사용할 클라이언트에 반환합니다.

이봐, 그것은 일종의 늦은 답변이지만 귀하의 솔루션은 내 첫 번째 답변에서 있었던 문제를 해결하는 것 같습니다. 물론 (id, token) 쌍을 일반 텍스트로 전송하지 않으려면 HTTPS를 사용해야합니다. 그러나 작동해야 할 것 같습니다!
Olivier Lance

서버에서 / me를 호출하고 모바일 클라이언트에서 사용할 자체 액세스 토큰을 생성하는 것이 좋습니다.
Der_Meister 2014 년

모바일 앱에 FB 비밀을 저장하는 것은 나쁜 습관이라는 것을 알았습니다. Facebook은 서버에만 저장하도록 조언합니다. developers.facebook.com/docs/opengraph/using-actions/...
Der_Meister

user_id와 access_token을 매번 API 서버로 보내면 (post / get params로). 누군가가 연결을 가로 챌 수 있다면 보안 구멍이 생길까요?
나단 마

@NathanDo 클라이언트와 API 서버간에 HTTPS를 사용하고 누군가 연결을 가로 채더라도 문제가되지 않아야합니다 (Heartbleed 유형의 취약점은 제쳐두고).
dcr

15

이것은 기본적으로 Chris의 업데이트 된 답변과 유사한 JWT (JSON Web Tokens)를 사용하여 구현 한 것입니다. Facebook JS SDK와 JWT를 사용했습니다.

여기에 내 구현이 있습니다.

  1. 클라이언트 : Facebook JS SDK를 사용하여 로그인하고 액세스 토큰을받습니다.

  2. 클라이언트 :/verify-access-token 엔드 포인트 를 호출하여 내 API에서 JWT를 요청 합니다.

  3. MyAPI : 액세스 토큰을 수신 /me하고 Facebook API의 끝점을 호출하여 확인합니다 .

  4. MyAPI : 액세스 토큰이 유효하면 데이터베이스에서 사용자를 찾고 사용자가 있으면 로그인합니다. 필수 필드를 페이로드로 사용하여 JWT를 만들고, 만료를 설정하고, 비밀 키로 서명하고, 클라이언트로 다시 보냅니다.

  5. 클라이언트 : JWT를 로컬 저장소에 저장합니다.

  6. 클라이언트 : 다음 API 호출에 대한 요청과 함께 토큰 (5 단계의 JWT)을 보냅니다.

  7. MyAPI : 비밀 키로 토큰의 유효성을 검사하고 토큰이 유효한 경우 토큰을 새 토큰으로 교환하고 API 응답과 함께 클라이언트에 다시 보냅니다. (이후 토큰 검증을위한 외부 API 호출은 없음) [토큰이 유효하지 않거나 만료 된 경우 클라이언트에 다시 인증을 요청하고 1부터 반복]

  8. 클라이언트 저장된 토큰을 새 토큰으로 교체하고 다음 API 호출에 사용합니다. 토큰 만료가 충족되면 토큰이 만료되어 API에 대한 액세스가 취소됩니다.

모든 토큰은 한 번만 사용됩니다.

보안 및 JWT에 대한 추가 답변 읽기

JWT는 얼마나 안전합니까?

JWT를 디코딩 할 수 있다면 어떻게 안전합니까?

사용자 식별 및 인증 토큰으로서의 JWT (JSON Web Tokens)


3
# 3은이어야한다고 생각 /debug_token하므로 토큰이 실제로 응용 프로그램에 맞는지 확인할 수 있습니다.
Peppe LG

2
access_token클라이언트에서 요청하지 마십시오 . "코드 워크 플로우"를 사용하십시오. 패스 codeMyAPI과 교환 페이스 북에 또 한 차례 여행을 codeaccess_token. 이것은 더 철저하게 여기 설명 : developers.facebook.com/docs/facebook-login/security을
omikron

5

나는 같은 질문에 대답하려고 노력하고 있으며 최근에 많은 독서를 겪고 있습니다 ...

"the"대답은 없지만 상황이 좀 더 명확 해졌습니다. 당신이 언급 한 기사 의 코멘트를 읽었 습니까? 정말 흥미롭고 도움이되었습니다.

결과적으로 첫 번째 기사가 작성된 이후로 상황이 어떻게 진화했는지에 비추어 볼 때 내가 할 일은 다음과 같습니다.

  • 모든 곳에서 HTTPS — HMAC, 서명, 임시 값 등을 잊을 수 있습니다.

  • OAuth2 사용 :

    • 내 앱 / 웹 사이트에서 인증 요청이 올 경우 앞서 언급 한 기사 에 대한 답장에 설명 된이 '트릭'(또는 변형) 을 사용하십시오 .

    • 제 경우에는 두 가지 유형의 사용자가 있습니다. 클래식 로그인 / 비밀번호 자격 증명을 가진 사용자와 Facebook Connect에 가입 한 사용자입니다.
      그래서 "페이스 북으로 로그인"버튼이있는 일반 로그인 양식을 제공하겠습니다. 사용자가 "클래식"자격 증명을 사용하여 로그인하면 grant_type=password.
      그가 페이스 북을 통해 로그인하기로 결정했다면 2 단계 과정이 될 것이라고 생각합니다.

      • 먼저 Facebook iOS SDK를 사용하여 FBSession을 엽니 다.
      • 이 작업이 완료되고 앱에 다시 제어권이 부여되면 해당 사용자의 Facebook ID를 얻을 수있는 방법이 있어야합니다. 내 서버에서 "FB 사용자 ID 사용"으로 인식 하는 확장 권한 과 함께이 ID 만 내 OAuth2 엔드 포인트로 보냅니다 .

이 모든 것에 대해 여전히 많이 연구하고 있으므로 완벽한 답이 아닐 수도 있습니다 ... 정답이 아닐 수도 있습니다! 그러나 나는 그것이 좋은 출발점이 될 것이라고 생각합니다. Facebook 인증에 "확장 권한 부여"를 사용하는 아이디어에는 제대로 작업을 수행하기 위해 등록해야 할 수 있습니까? 잘 모르겠습니다.

어쨌든, 내가 당신을 조금이라도 도울 수 있기를 바랍니다. 그리고 적어도이 문제에 대한 최선의 해결책을 찾기 위해 토론을 시작할 수 있기를 바랍니다. :)

최신 정보
Facebook 로그인은 댓글에서 지적한 해결책이 아닙니다. 누구나 임의의 사용자 ID를 보내고 API에서이 사용자로 로그인 할 수 있습니다.

이렇게하면 어떨까요?

  • "Facebook 로그인"버튼이있는 로그인 양식 표시
  • 이 로그인 방법을 선택한 경우 Facebook SDK처럼 작동합니다. 인증 서버에서 웹 페이지를 열면 Facebook 로그인이 시작됩니다.
  • 사용자가 로그인하면 Facebook은 리디렉션 URL을 사용하여 확인합니다. 해당 URL이 인증 서버의 다른 끝점을 가리 키도록합니다 (아마도 앱에서 호출이 왔음을 나타내는 추가 매개 변수가 있습니까?).
  • 인증 엔드 포인트에 도달하면 인증은 Facebook SDK와 마찬가지로 사용자를 안전하게 식별하고 FB 사용자 ID / FB 세션을 유지하며 사용자 지정 URL 체계를 사용하여 앱에 액세스 토큰을 반환 할 수 있습니다.

더 좋아 보이나요?


1
당신의 답변에 감사드립니다! 나는 당신이 말한 대부분을 생각했지만 FB iOS SDK를 사용하고 Facebook 사용자 ID를 보내는 데있어 가장 큰 관심사는 API 엔드 포인트에 원하는 ID를 보내고 주장하는 것이 쉽지 않다는 것입니다. 다른 사용자? 이것은 내가 보통 붙어 치울 곳이다 ..
아담

과연! 이 솔루션은 ... 어떻게 든 자신의 인증 서버를 통해 가야 그래서 ... 그것에 대해 생각하는 나에게 아무의 바보
올리비에 랜스

다른 솔루션 아이디어로 내 답변을 업데이트했지만 원래 질문에서 언급했음을 깨달았습니다! 나는 ... 순간에 무엇을 볼 수 없습니다
올리비에 랜스에게
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.