OAuth 2.0 메커니즘

이 문서에서는 IMAP AUTHENTICATE, POP AUTH, SMTP AUTH 명령어에 사용하기 위한 SASL XOAUTH2 메커니즘을 정의합니다. 이 메커니즘을 통해 OAuth 2.0 액세스 토큰을 사용하여 사용자의 Gmail 계정에 인증할 수 있습니다.

OAuth 2.0 사용

먼저 OAuth 2.0을 사용하여 Google API에 액세스하기를 숙지하세요. 해당 문서에서는 OAuth 2.0의 작동 방식과 클라이언트를 작성하는 데 필요한 단계를 설명합니다.

작동하는 예시를 보려면 샘플 XOAUTH2 코드를 둘러보세요.

OAuth 2.0 범위

IMAP, POP, SMTP 액세스의 범위는 https://mail.google.com/입니다. IMAP, POP 또는 SMTP 앱의 전체 메일 범위에 대한 액세스를 요청하는 경우 Google API 서비스: 사용자 데이터 정책을 준수해야 합니다.

  • 승인되려면 앱에서 https://mail.google.com/의 전체 사용률을 표시해야 합니다.
  • 앱에 https://mail.google.com/가 필요하지 않다면 Gmail API로 이전하고 더 세분화된 제한된 범위를 사용하세요.

Google Workspace의 도메인 전체 위임

서비스 계정을 사용하여 Google Workspace 도메인 전체 위임을 통해 IMAP을 통해 사용자의 메일함에 액세스하려는 경우 Google Workspace 대신 범위 https://www.googleapis.com/auth/gmail.imap_admin를 사용하여 클라이언트를 승인할 수 있습니다.

이 범위로 승인되면 IMAP 연결이 다르게 작동합니다.

  • 사용자가 Gmail 설정에서 라벨의 'IMAP에 표시'를 사용 중지한 경우에도 모든 라벨이 IMAP을 통해 표시됩니다.
  • 사용자가 Gmail 설정의 '폴더 크기 제한'에 설정한 설정과 관계없이 모든 메일은 IMAP을 통해 표시됩니다.

SASL XOAUTH2 메커니즘

XOAUTH2 메커니즘을 사용하면 클라이언트가 OAuth 2.0 액세스 토큰을 서버로 전송할 수 있습니다. 프로토콜은 다음 섹션에 표시된 인코딩된 값을 사용합니다.

초기 클라이언트 응답

SASL XOAUTH2 초기 클라이언트 응답의 형식은 다음과 같습니다.

base64("user=" {User} "^Aauth=Bearer " {Access Token} "^A^A")

RFC 4648에 정의된 base64 인코딩 메커니즘을 사용합니다. ^A는 Control+A (\001)를 나타냅니다.

예를 들어 base64 인코딩 전에 초기 클라이언트 응답은 다음과 같을 수 있습니다.

user=someuser@example.com^Aauth=Bearer ya29.vF9dft4qmTc2Nvb3RlckBhdHRhdmlzdGEuY29tCg^A^A

base64 인코딩 후에는 다음과 같이 표시됩니다 (가독성을 위해 줄바꿈이 삽입됨).

dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlYXJlciB5YTI5LnZGOWRmdDRxbVRjMk52
YjNSbGNrQmhkSFJoZG1semRHRXVZMjl0Q2cBAQ==

오류 응답

오류를 일으키는 초기 클라이언트 응답으로 인해 서버는 다음 형식의 오류 메시지가 포함된 챌린지를 전송합니다.

base64({JSON-Body})

JSON-Body에는 status, schemes, scope의 세 가지 값이 포함됩니다. 예를 들면 다음과 같습니다.

eyJzdGF0dXMiOiI0MDEiLCJzY2hlbWVzIjoiYmVhcmVyIG1hYyIsInNjb3BlIjoiaHR0cHM6Ly9t
YWlsLmdvb2dsZS5jb20vIn0K

base64 디코딩 후에는 다음과 같이 표시됩니다 (명확성을 위해 형식이 지정됨).

{
  "status":"401",
  "schemes":"bearer",
  "scope":"https://mail.google.com/"
}

SASL 프로토콜은 클라이언트가 이 챌린지에 대해 빈 응답을 보내도록 요구합니다.

IMAP 프로토콜 교환

이 섹션에서는 Gmail IMAP 서버에서 SASL XOAUTH2를 사용하는 방법을 설명합니다.

초기 고객 응답

SASL XOAUTH2 메커니즘으로 로그인하려면 클라이언트는 메커니즘 매개변수 XOAUTH2와 위에 구성된 초기 클라이언트 응답을 사용하여 AUTHENTICATE 명령어를 호출합니다. 예를 들면 다음과 같습니다.

[connection begins]
C: C01 CAPABILITY
S: * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA XLIST
CHILDREN XYZZY SASL-IR AUTH=XOAUTH2 AUTH=XOAUTH
S: C01 OK Completed
C: A01 AUTHENTICATE XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvb
QFhdXRoPUJlYXJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG
1semRHRXVZMjl0Q2cBAQ==
S: A01 OK Success
[connection continues...]

IMAP 프로토콜 교환에 관한 참고사항:

  • IMAP AUTHENTICATE 명령어는 RFC 3501에 설명되어 있습니다.
  • SASL-IR 기능을 사용하면 AUTHENTICATE 명령어의 첫 번째 줄에 초기 클라이언트 응답을 전송할 수 있으므로 인증에 왕복이 한 번만 필요합니다. SASL-IR은 RFC 4959에 설명되어 있습니다.
  • AUTH=XOAUTH2 기능은 서버가 이 문서에 정의된 SASL 메커니즘을 지원한다고 선언하며, 이 메커니즘은 XOAUTH2를 AUTHENTICATE 명령어의 첫 번째 인수로 지정하여 활성화됩니다.
  • AUTHENTICATECAPABILITY 명령어의 줄바꿈은 명확성을 위해 추가된 것이며 실제 명령어 데이터에는 표시되지 않습니다. 전체 base64 인수는 공백이 포함되지 않은 하나의 연속된 문자열이어야 하므로 전체 AUTHENTICATE 명령어가 한 줄의 텍스트로 구성되어야 합니다.

오류 응답

인증 실패는 IMAP AUTHENTICATE 명령어를 통해서도 반환됩니다.

[connection begins]
S: * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA XLIST
CHILDREN XYZZY SASL-IR AUTH=XOAUTH2
S: C01 OK Completed
C: A01 AUTHENTICATE XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQ
FhdXRoPUJlYXJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1s
emRHRXVZMjl0Q2cBAQ==
S: + eyJzdGF0dXMiOiI0MDEiLCJzY2hlbWVzIjoiYmVhcmVyIG1hYyIsInNjb
3BlIjoiaHR0cHM6Ly9tYWlsLmdvb2dsZS5jb20vIn0K
C:
S: A01 NO SASL authentication failed

IMAP 프로토콜 교환 관련 참고사항

  • 클라이언트는 챌린지에 오류 메시지가 포함된 빈 응답(\'\r\n\')을 전송합니다.

POP 프로토콜 교환

이 섹션에서는 Gmail POP 서버에서 SASL XOAUTH2를 사용하는 방법을 설명합니다.

초기 클라이언트 응답

SASL XOAUTH2 메커니즘으로 로그인하기 위해 클라이언트는 XOAUTH2의 메커니즘 매개변수와 위에 구성된 초기 클라이언트 응답을 사용하여 AUTH 명령어를 호출합니다. 예를 들면 다음과 같습니다.

[connection begins]
C: AUTH XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlYX
JlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMjl0
Q2cBAQ==
S: +OK Welcome.
[connection continues...]

POP 프로토콜 교환에 관한 참고사항:

  • POP AUTH 명령어는 RFC 1734에 설명되어 있습니다.
  • AUTH 명령어의 줄바꿈은 명확성을 위해 추가된 것이며 실제 명령어 데이터에는 표시되지 않습니다. 전체 base64 인수는 공백이 포함되지 않은 하나의 연속된 문자열이어야 하므로 전체 AUTH 명령어가 한 줄의 텍스트로 구성되어야 합니다.

오류 응답

인증 실패는 POP AUTH 명령어를 통해서도 반환됩니다.

[connection begins]
C: AUTH XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlY
XJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMj
l0Q2cBAQ==
S: + eyJzdGF0dXMiOiI0MDAiLCJzY2hlbWVzIjoiQmVhcmVyIiwic2NvcGUi
OiJodHRwczovL21haWwuZ29vZ2xlLmNvbS8ifQ==

SMTP 프로토콜 교환

이 섹션에서는 Gmail SMTP 서버에서 SASL XOAUTH2를 사용하는 방법을 설명합니다.

초기 클라이언트 응답

XOAUTH2 메커니즘으로 로그인하기 위해 클라이언트는 XOAUTH2의 메커니즘 매개변수와 위에 구성된 초기 클라이언트 응답을 사용하여 AUTH 명령어를 호출합니다. 예를 들면 다음과 같습니다.

[connection begins]
S: 220 mx.google.com ESMTP 12sm2095603fks.9
C: EHLO sender.example.com
S: 250-mx.google.com at your service, [172.31.135.47]
S: 250-SIZE 35651584
S: 250-8BITMIME
S: 250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
S: 250-ENHANCEDSTATUSCODES
S: 250 PIPELINING
C: AUTH XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlY
XJlciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMj
l0Q2cBAQ==
S: 235 2.7.0 Accepted
[connection continues...]

SMTP 프로토콜 교환에 관한 유의사항은 다음과 같습니다.

  • SMTP AUTH 명령어는 RFC 4954에 설명되어 있습니다.
  • AUTH 명령어의 줄바꿈은 명확성을 위해 추가된 것이며 실제 명령어 데이터에는 표시되지 않습니다. 전체 base64 인수는 삽입된 공백 없이 연속된 하나의 문자열이어야 하므로 전체 AUTH 명령어는 한 줄의 텍스트로 구성됩니다.

오류 응답

인증 실패는 SMTP AUTH 명령어를 통해서도 반환됩니다.

[connection begins]
S: 220 mx.google.com ESMTP 12sm2095603fks.9
C: EHLO sender.example.com
S: 250-mx.google.com at your service, [172.31.135.47]
S: 250-SIZE 35651584
S: 250-8BITMIME
S: 250-AUTH LOGIN PLAIN XOAUTH XOAUTH2
S: 250-ENHANCEDSTATUSCODES
S: 250 PIPELINING
C: AUTH XOAUTH2 dXNlcj1zb21ldXNlckBleGFtcGxlLmNvbQFhdXRoPUJlYXJl
ciB5YTI5LnZGOWRmdDRxbVRjMk52YjNSbGNrQmhkSFJoZG1semRHRXVZMjl0Q2cB
AQ==
S: 334 eyJzdGF0dXMiOiI0MDEiLCJzY2hlbWVzIjoiYmVhcmVyIG1hYyIsInNjb
3BlIjoiaHR0cHM6Ly9tYWlsLmdvb2dsZS5jb20vIn0K
C:
S: 535-5.7.1 Username and Password not accepted. Learn more at
S: 535 5.7.1 https://support.google.com/mail/?p=BadCredentials hx9sm5317360pbc.68
[connection continues...]

SMTP 프로토콜 교환에 관한 유의사항:

  • 클라이언트는 챌린지에 오류 메시지가 포함된 빈 응답(\'\r\n\')을 전송합니다.

참조