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의 3가지 값이 포함되어 있습니다. 예를 들면 다음과 같습니다.

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 인수는 공백이 없는 연속된 문자열 1개여야 합니다. 그래야 전체 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 인수는 공백이 없는 연속된 문자열 1개여야 합니다. 그래야 전체 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 인수는 공백이 없는 연속된 문자열 1개여야 합니다. 그래야 전체 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')을 보냅니다.

참조