인증 토큰 만들기
인증 절차에 사용할 인증서 및 개인키는 Salesforce Connected App 설정 설명에서 사용된 인증서(company.crt)에 대응하는 만든 키스토어 또는 개인키를 사용합니다. company.jks, company.key 파일을 프로젝트의 루트 폴더에 복사를 해둡니다. 실제로는 jks, key 둘 중에 한가지만 필요합니다. 뒤에서 설명하는 인증서/개인키 사용 방법에 따라 선택을 하시면 됩니다. Client Key와 Connected App에 접속할 수 있는 사용자 Id도 준비를 해둡니다.
필요한 패키지 설치
Python에서 JWT 인증 토큰을 발급받으려면 몇가지 패키지를 설치하여야 합니다.
Visual Studio Code의 터미널 창에서 아래의 명령을 실행합니다. 이때 Python 프로젝트는 virtualenv 가상 환경이 활성화 되어있어야 합니다.
pip install requests cryptography pyjwt pyjks
Windows 환경에서 pyjwt 패키지를 설치할 때 Microsoft C++ Build Tools 개발 환경을 필요로 합니다. 다운로드한 설치 파일을 실행하고 기본 설치 옵션을 모두 설치합니다.

설치되는 패키지는 다음과 같습니다.
-
requests : Web 서비스 호출을 위한 패키지
-
pyjwt : JWT 인코딩/디코딩을 처리해주는 패키지
-
pyjks : JKS 키스토어 파일을 조작할 수 있는 패키지
-
cryptography : pyjwt 패키지가 의존하는 패키지
모듈 만들기
인증 받기 코드에 사용할 Python 모듈을 생성합니다.
이 설명에서는 virtualenv 가상 환경 프로젝트를 기준으로 설명을 합니다.
-
Python 프로젝트 명의 오른쪽 New File 아이콘을 클릭합니다.

-
만들어지는 모듈에 대한 파일 이름으로 Auth.py를 입력합니다.

-
같은 방법으로 sample.py 파일을 생성합니다.
코드 구성
인증을 받기 위하여 Salesforce Connnected App에 전송하는 토큰은 다음과 같이 .으로 연결된 3부분으로 이루어져 있습니다.
[JWT 헤더].[인증 요청정보].[개인키로 암호화된 헤더+요청정보] (JWT Header.Claim Payload.Header + Signed Payload)
순서대로 만들어 보도록 하겠습니다.
-
Auth.py모듈 윗 부분에 아래의 내용을 추가를 합니다.import requests import jwt import time import textwrap import base64 -
가장 먼저 개인키(PrivateKey)를 프로그램에 적재하여야 합니다. 개인키를 적재하는 방법은 아래의 세가지 방법이 있으니 상황에 맞는 방법을 사용하시면 됩니다.
-
JKS 키스토어의 개인키를 적재하는 방법
def getPrivateKeyFromJKS(filePath, alias, password): import jks keyStore = jks.KeyStore.load(filePath, password) pkEntry = keyStore.private_keys[alias] decodedKey = base64.b64encode(pkEntry.pkey_pkcs8).decode('ascii') pkcs8PEM = "\r\n".join([ "-----BEGIN PRIVATE KEY-----", "\r\n".join(textwrap.wrap(decodedKey, 64)), "-----END PRIVATE KEY-----" ]) return pkcs8PEMsample.py파일에 아래의 내용을 추가합니다.import Auth import json import textwrap def main(): privateKey = Auth.getPrivateKeyFromJKS("company.jks", "company", "password") print(privateKey) main()터미널에서 아래의 명령을 실행해봅니다.
python sample.pycompany.key파일의 내용과 같은 내용이 표시가 되면 정상 동작하는것입니다. -
개인키 파일의 개인키를 적재하는 방법
Auth.py파일에 아래의 메소드를 추가합니다.def getPrivateKeyFromFile(filePath): fd = open(filePath, "r") privateKey = fd.read() return privateKeysample.py파일에 아래의 내용을 추가합니다.import Auth import json import textwrap def main(): privateKey = Auth.getPrivateKeyFromFile("company.key") print(privateKey) main()터미널에서 아래의 명령을 실행해봅니다.
python sample.pycompany.key : 개인키 파일입니다.
-
개인키 파일의 개인키를 스트링으로 적재하는 방법
sample.py파일의main메소드를 다음과 같이company.key의 내용을 직접 변수에 지정하여 사용할 수도 있습니다.import Auth import json import textwrap def main(): privateKey = textwrap.dedent(""" -----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDN4c80VU9yjbAu JWq3RYPBsLnP2wcipVdGIzPYLqyXUq2GBlhyaLjN0NI5mO+AyXE8FSJtD/Y22ILQ ... ... ... Qmh4OV5ZHXwx5R6ffAOAwAY= -----END PRIVATE KEY----- """).encode() main()
위의 세가지 방법중의 하나를 사용하도록 합니다.
-
-
인증 요청 Token을 만들기 위하여
Auth모듈에 아래의 메소드를 추가합니다.def getToken(consumerKey, loginUrl, loginUser, privateKey): print('Generating signed JWT assertion...') claim = { 'iss': consumerKey, 'sub': loginUser, 'aud': loginUrl, 'exp': int(time.time()) + 300, } encoded = jwt.encode(claim, privateKey, algorithm='RS256', headers={'alg':'RS256'}) return encoded-
clientId : ConnectedApp에서 제공하는 Consumer Key 입니다.
-
loginUrl : login.salesforce.com 또는 test.salesforce.com을 사용합니다.
-
loginId : ConnectedApp에서 Profile 또는 Permission Set으로 잡속이 허용된 이메일 형식의 사용자 계정입니다.
이 코드로 생성되는 Token 값은 Salesforce의 JWT Bearer 플로우를 위한 값입니다. 다른 시스템들은 Heade와 Claim이 다른 형식을 사용할 수 있습니다.
sample.py파일의main메소드를 아래와 같이 수정하고 터미널에서python sample.py를 실행해 봅니다.def main(): privateKey = Auth.getPrivateKeyFromFile("company.key") ////////////////// // Make a Token // ////////////////// String consumerKey = "3MVG9YDQS5WtC11q60F............QYX68awYhUzKVMMB"; String loginUrl = "https://login.salesforce.com/"; String loginUser = "username@example.com"; token = Auth.getToken(consumerKey, loginUrl, loginUser, privateKey); print(token)eyJhbGciOiJSUzI1NiJ9.ey....와 같은 인코딩된 문자열이 출력되면 정상입니다. -