사회학습지-주행골격

처음부터 우리는 a와 a가 있었지만, 그것들은 연락이 없었다.다음 단계에서는 프로덕션 환경에 구축된 시스템을 대상으로 스텁 없이 전체 테스트를 수행하는 walking skeleton을 만듭니다.이 절에서 우리는 CORS과 신분 검증 등 미지의 문제를 처리해야 한다.

결실


검증된 "안녕하세요, 세계!"API 끝점, 텍스트가 React 응용 프로그램의 대시보드에 표시됩니다.

API Ping 무단


우리 좀 더 간단한 문제를 해결하는 것부터 시작합시다.다음 몇 가지 단계에서 인증을 처리할 것입니다. 그러나 지금은 전방에서 후방으로 보내는 요청만 주목하고 결과를 보여 드리겠습니다.
API 프로젝트에 /ping포인트가 있습니다.이 문서의 출처는 src/controllers/ping이다.
@ping.route('/', methods=['GET'])
@ping.route('/ping', methods=['GET'])
def hello_world():
    """
    Monitor endpoint
    ---
    tags:
      - ping
    responses:
      200:
        description: Hello, world!
    """
    return 'Hello, world!'

API에 갈고리 매핑


나의 반응 능력은 예전처럼 그렇게 예민하지 않다.기능 구성 요소를 사용하고 있는데 componentDidMountcomponentWillMount의 생명주기 방법이 useEffect으로 바뀌었다는 것을 발견했다. 여기서 add-state-and-lifecycle-methods-to-function-components-with-react-hooks에 대한 설명을 찾을 수 있다.다음 몇 달 동안 나는 이미 이 기능을 이용했다.
프로젝트에 axios을 추가했습니다. 약속 기반 HTTP 클라이언트입니다.이것은 API 호출 패키지를 통해 지원됩니다.그런 다음 예상한 대로 엔드포인트 호출을 시도할 때 다음과 같은 HTTP 오류가 발생했습니다.
Access to XMLHttpRequest at 'https://dev3l-learning-journal.herokuapp.com/ping' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Python API로 다시 전환하려면 다음 코드 세션을 응용 프로그램 초기화에 추가해야 합니다.만약 우리가 회사 생산 환경에서 일한다면 *을 우리의 허용 원시치로 삼는 것은 이상적이지 않다.반대로, 우리는 그것을 이미 알고 있는 전단역으로 설정할 것이다.
@app.after_request
def apply_cors(response):
    response.headers.set("Access-Control-Allow-Origin", "*")
    response.headers.set("Access-Control-Allow-Methods", "GET,POST,OPTIONS")
    response.headers.set("Access-Control-Allow-Headers",
                         "Origin, X-Requested-With, Content-Type, Accept, Authorization")

    return response
배치 후, 우리는 미경험증의 단점이 Hello, world! 메시지로 되돌아오는 데 성공했는지 검증할 수 있다.
  useEffect(() => {
    async function fetchData() {
      const dataResponse = await axios.get('https://dev3l-learning-journal.herokuapp.com/ping');
      const message = dataResponse.data;

      setMessage(message);
    }
    fetchData();
  }, []);

권한을 부여하다


다음에 인증을 목표 노드에 추가해야 합니다.이를 위해서는 API 서버에 Firebase를 추가해야 합니다.Firebase에는 많은 사용 가능한 기능이 있지만 인증만 사용합니다.id 영패를 지정하면 영패를 검증하고 사용자를 얻을 수 있습니다.Pyrebase은Firebase를 둘러싸고 호출된 파이톤 패키지입니다.따라서 프로젝트에 추가하고 인증 연결을 설정하는 데 착수합니다.Firebase auth 객체에는 id 토큰을 검증하는 방법이 포함되어 있습니다.
firebase = firebase_instance()
auth = firebase.auth()
account_info = auth.get_account_info(id_token)
클라이언트는 서비스 계정을 사용하여 관리 관점에서 API를 사용합니다.Firebase 콘솔 설정 페이지를 통해 쉽게 만들 수 있습니다.불만 사항은 자격 증명 JSON 파일을 사용하여 초기화할 때 사용자를 검증하는 것입니다.우리는 진정한 기밀 관리 시스템이 없기 때문에 나는 매우 간단한 방법을 사용하여 JSON 파일의 private_key 변수를 환경 변수로 바꾸었다.
import json
import os

import pyrebase

FIREBASE_API_KEY = os.environ.get("FIREBASE_API_KEY", "api_key")
FIREBASE_AUTH_DOMAIN = os.environ.get("FIREBASE_AUTH_DOMAIN", "auth_domain")
FIREBASE_DATABASE_URL = os.environ.get("FIREBASE_DATABASE_URL", "database_url")
FIREBASE_STORAGE_BUCKET = os.environ.get("FIREBASE_STORAGE_BUCKET", "storage_bucket")
FIREBASE_ADMIN_PRIVATE_KEY = os.environ.get("FIREBASE_ADMIN_PRIVATE_KEY", "admin_private_key")

SERVICE_ACCOUNT_PATH = "./data/firebase-adminsdk.json"
SERVICE_ACCOUNT_PATH_TEMP = "./data/_firebase-adminsdk.json"

config = {
    "apiKey": FIREBASE_API_KEY,
    "authDomain": FIREBASE_AUTH_DOMAIN,
    "databaseURL": FIREBASE_DATABASE_URL,
    "storageBucket": FIREBASE_STORAGE_BUCKET,
    "serviceAccount": SERVICE_ACCOUNT_PATH_TEMP
}

_firebase = None


def firebase_instance():
    global _firebase

    if _firebase:
        return _firebase

    # handle newlines
    firebase_admin_private_key = FIREBASE_ADMIN_PRIVATE_KEY.replace("\\n", "\n")

    with open(SERVICE_ACCOUNT_PATH) as service_account_file:
        service_account_json = json.load(service_account_file)

    service_account_json['private_key'] = firebase_admin_private_key

    with open(SERVICE_ACCOUNT_PATH_TEMP, 'w') as temp_service_account_file:
        json.dump(service_account_json, temp_service_account_file)

    _firebase = pyrebase.initialize_app(config)
    return _firebase

Firebase가 추가됨에 따라 Heroku 응용 프로그램에 환경 변수를 추가해야 합니다.

이 변수들은 Netlify를 입력한 변수와 유사하지만 FIREBASE_ADMIN_PRIVATE_KEY 변수만 증가했다.이 값은 서비스 계정을 만들 때Firebase에서 다운로드한 adminsdk.json에서 복사한 것입니다.프로젝트 firebase-adminsdk.json의 파일은 GIT에 서명되었으나 생성된 파일 _firebase-adminsdk.json은 에 나열되어 있습니다.gitignore, 그래서 업데이트되지도, 의외로 대중 앞에 떠밀리지도 않습니다.flask_auth을 사용하여 엔드포인트에 추가할 수 있는 인증 장식기를 만들었습니다.
from flask_httpauth import HTTPTokenAuth
from requests import HTTPError

from src.dao.firebase import firebase_instance

auth = HTTPTokenAuth(scheme='Bearer')


@auth.verify_token
def verify_token(id_token):
    # firebase singleton
    auth = firebase_instance().auth()

    try:
        auth.get_account_info(id_token)
    except HTTPError:
        return False

    return True
이때 우리는 사용자에게 관심이 없고 효과적인 id_token이 단점으로 전달되는 것만 관심을 가진다.다음에 우리는 새로운 단점 ping_authenticated을 만들었는데 이것은 @auth.login_required 장식기를 이용한다.
@ping.route('/ping_authenticated', methods=['GET'])
@auth.login_required
def hello_world_authenticated():
    """
    Authenticated monitor endpoint
    ---
    tags:
      - ping_authenticated
    responses:
      200:
        description: Hello, authenticated world!
    """
    return 'Hello, authenticated world!'

인증 요청


이제 API를 설정하여 프런트엔드로 전환합니다.우선, 우리는 서비스를 만들어야 한다. 이 서비스는 적당한 헤더를 추가한axios 대상을 되돌려준다.
// axios_service.js
import axios from 'axios';

export async function axiosRequest(currentUser) {
  const idToken = await currentUser.getIdToken(true);
  axios.defaults.headers.common['Authorization'] = 'Bearer ' + idToken;

  return axios;
}
마지막으로, 우리는 그것을 모두 계기판에 묶었다.
  useEffect(() => {
    async function fetchData() {
      const dataResponse = await axios.get(SERVER_API_URL + '/ping');
      const message = dataResponse.data;
      setMessage(message);

      const request = await axiosRequest(currentUser);
      const authenticatedDataResponse = await request.get(SERVER_API_URL + '/ping_authenticated');
      const authenticatedMessage = authenticatedDataResponse.data;
      setAuthenticatedMessage(authenticatedMessage);
    }
    fetchData();
  }, []);

결론


아직 엔드 유저를 위해 많은 가치 있는 기능을 추가하지는 않았지만, 우리는 이미 대량의 기술적 위험을 극복하고 더욱 복잡한 해결 방안을 위해 길을 닦았다.Firebase의 인증을 이용하여 우리는 시스템에 OAuth 솔루션을 만들었습니다. 백엔드와 전면에 몇 십 줄의 코드만 있습니다.그 밖에 주행 골격 기술을 사용하여 제시한 해결 방안은 이미 생산 환경에서 검증되었다.미래의 게시물에서 우리는 최종 제품에 근육과 고기를 첨가하는 가치 있는 기능을 실시하기 시작할 것이다.

좋은 웹페이지 즐겨찾기