Firebase 클라우드 기능:사용자 토큰 확인

어제 나는 DeckDeckGo의 핵심 함수를 재구성하기 시작하여 새로운 Firebase Cloud Functions를 발표했다. 이것은 HTTP requests를 통해 촉발할 수 있다.
내가 그것의 접근 권한을 보호하려고 할 때, 슬그머니 요청하는 것을 피하기 위해서, 나는 나의 한 사람 previous blog post 을 따라 소유자의 도움으로 그것을 보호한다.
일단 내가 이 특성의 첫걸음을 시험해 보았을 때, 나는 사실상 그것이 나의 용례에 적합한 정확한 해결 방안이 아니라는 것을 알아차렸다.나는 사용자 영패를 사용해서 접근 권한을 부여해야만 했다.

클라우드 기능에서 사용자의 영패를 검증하다
해결 방안을 아는 사람들에게는 어리석게 들릴 수도 있지만, 실제로는 Firebase 클라우드 함수에서 사용자의 영패를 검증하는 방법을 찾는 데 상당한 시간이 걸렸다.
백엔드에서 이 해결 방안을 실현하려고 시도했습니다. 이것은 잘못된 시작입니다. Authenticate with a backend server 에서 라이브러리 google-auth-library 를 사용한 것과 같습니다.나는 이 해결 방안을 실현하는 데 많은 시간을 들였고, 내 프로젝트에 필요한 OAuthCLIENT_ID 정보를 어디서 찾을 수 있는지 찾았는데, 결국 이 과정을 시도하는 과정에서 다음과 같은 오류가 발생했다.
No pem found for envelope: {"alg":"RS256","kid":"...","typ":"JWT"}
마지막으로 여러 차례의 시도를 거쳐 나는 실패를 받아들이고 구글에서 해결 방안을 검색했다.다행히도 나에게Stackoverflow question의 마지막 부분에서 나는 Will의 대답으로 인해 기호화폐를 더욱 쉽게 검증할 수 있는 방법이 있다는 것을 발견했다.
사실Admin documentation을 알았더라면Firebase가 이 수요를 해결하는 내장 방법이라는 것을 알았을 것이다.

The Firebase Admin SDK has a built-in method for verifying and decoding ID tokens. If the provided ID token has the correct format, is not expired, and is properly signed, the method returns the decoded ID token. You can grab the uid of the user or device from the decoded token.


일단 내가 이 보석을 발견하면 내 뇌가 최종적으로 클릭할 때 나는 작은 실용 기능을 실현할 수 있다.
import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';

export async function verifyToken(
                request: functions.Request): Promise<boolean> {
  try {
    const token: string | undefined = await getToken(request);

    if (!token) {
      return false;
    }

    const payload: admin.auth.DecodedIdToken = 
                   await admin.auth().verifyIdToken(token);

    return payload !== null;
  } catch (err) {
    return false;
  }
}

async function getToken(request: functions.Request): 
                       Promise<string | undefined> {
  if (!request.headers.authorization) {
    return undefined;
  }

  const token: string = 
        request.headers.authorization.replace(/^Bearer\s/, '');

  return token;
}
내가 테스트payloadnull에서 영패가 유효하다고 생각하는지 여부는 주의하지만, 나는 그것을 필요로 하지 않을 수도 있다고 생각한다.방법verifyIdToken이 잘못되었을 때 오류를 던졌습니다.
또한 HTTP가 요청한 headers 에서 전달할 사용자 영패를 제외하고는 키워드 Bearer 를 접두사로 사용했음을 알 수 있습니다.
예를 들어, 토큰 ID975dd9f6를 지정하면 HTTP POST 요청은 다음과 같습니다.
#!/bin/sh
    curl -i
         -H "Accept: application/json"
         -H "Authorization: Bearer 975dd9f6"
         -X POST https://us-central1-yolo.cloudfunctions.net/helloWorld

익명 사용자만
누구나 시도할 수 있다DeckDeckGo. 만약 당신이 단지 시도하고 싶을 뿐이라면 강제로 로그인하거나 미리 로그인할 필요가 없다.이것은 우리에게 있어서 정말 중요하다. 우리는 데이터나 사용자 수를 추구하는 것이 아니라, 그것을 사용하고 싶거나 사용하고 싶지 않은 사용자를 위해 프레젠테이션 편집기를 개발하는 것이다😉.
이는 사용자가 프레젠테이션 원고를 공개적으로 공유하고 싶다면'이것은 테스트'나'Yolo'카드를 너무 많이 발표하고 싶지 않기 때문이다. 가능하면 무의미한 공공 내용을 각각 피하고'발표 과정'(프레젠테이션 원고를 온라인 점진적 웹 응용 프로그램으로 전환하고 배치하는 과정)을 서명 사용자로 제한할 것이다.
이러한 과정에 대해Firebase가 제공하는 능력을 사용합니다anonymous users.
이것이 바로 내가 기호화폐를 검증하는 것 외에 검사 정보를 추가한 이유다.다행히도, 이것도 쉽게 해결할 수 있다. 왜냐하면 payload 함수가 제공한 verifyToken에 이런 정보가 확실히 포함되어 있기 때문이다.
const payload: admin.auth.DecodedIdToken = 
                   await admin.auth().verifyIdToken(token);

return payload !== null &&
       payload.firebase.sign_in_provider !== 'anonymous';

불러오는 호출 함수
관심 있으시다면 TypeScript와 Firebase Auth를 사용하는 응용 프로그램에서 함수 호출에 대해 위와 같은 내용을 제공하는 방법bearer입니다.
helloWorld(): Promise<void> {
  return new Promise<void>(async (resolve, reject) => {
    try {
      const token: string = 
            await firebase.auth().currentUser.getIdToken();

      const functionsUrl: string = 
           'https://us-central1-yolo.cloudfunctions.net';

      const rawResponse: Response = 
            await fetch(`${functionsUrl}/helloWorld`, {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
          Authorization: `Bearer ${token}`,
        },
        body: JSON.stringify({
          something: 'a value'
        }),
      });

      if (!rawResponse || !rawResponse.ok) {
        reject('Post failed etc.');
        return;
      }

      resolve();
    } catch (err) {
      reject(err);
    }
  });
}

위의 체리
HTTP 요청을 처리하는 첫 번째 함수를 구현했기 때문에 CORS를 처리해야 합니다.빠른 구글 검색과Gist 제공CoderTonyB이 해결 방안을 제공했다.
expressjs/cors는 기능 항목에 설치해야 한다.
npm i cors --save && npm i @types/cors --save-dev
마지막으로, 효과적으로 실현되기 전에, 처리 프로그램을 사용하여 CORS 요청을 처리해야 한다.
import * as functions from 'firebase-functions';
import * as cors from 'cors';

export const helloWorld = functions.https.onRequest(myHelloWorld);

async function helloWorld(request: functions.Request,
                          response: functions.Response<any>) {
  const corsHandler = cors({origin: true});

  corsHandler(request, response, async () => {
      response.send('Yolo');
  });
}

가져가다
사실상 새로운 기능을 잘못 개발하기 시작하고 곧 시간을 잃기 쉽다.내가 말하고 싶은 것은 심호흡이나 휴식이 관건이지만, 간혹 어떤 일이 발생할 수 있다는 것이다😉. 하지만, 만약 당신이 이런 상황을 피하는 절묘한 건의와 기교가 있다면, 나에게 알려주세요. 나는 이런 것을 듣고 매우 궁금합니다!
만약 당신이 결과에 대해 궁금하다면, 우리를 주목해 주십시오. 왜냐하면 우리는 다음 주에 개발자를 위해 매우 멋진 기능을 발표할 수 있기 때문입니다🚀.
무한원까지!
다윗
표지 사진 작성자Nigel TadyanehondoUnsplash

좋은 웹페이지 즐겨찾기