কীভাবে কেবল ফায়ারবেস অনুমোদনপ্রাপ্ত ব্যবহারকারীদের মঞ্জুরি দেওয়ার জন্য ফায়ারবেস ক্লাউড ফাংশন এইচটিটিপি শেষ পয়েন্টটি কীভাবে রক্ষা করবেন?


141

নতুন ফায়ারবেস ক্লাউড ফাংশন সহ আমি আমার কিছু এইচটিটিপি শেষ প্রান্তটি ফায়ারবেসে স্থানান্তরিত করার সিদ্ধান্ত নিয়েছি। সবকিছু দুর্দান্ত কাজ করে ... তবে আমার নীচের বিষয়টি আছে। আমার এইচটিটিপি ট্রিগার (ক্লাউড ফাংশন) দ্বারা নির্মিত দুটি সমাপ্তি রয়েছে

  1. ব্যবহারকারী তৈরি করতে এবং একটি ফায়ারবেস অ্যাডমিন এসডিকে দ্বারা উত্পাদিত কাস্টম টোকন প্রদানের জন্য একটি এপিআই এন্ডপয়েন্ট।
  2. নির্দিষ্ট ব্যবহারকারীর বিশদ আনার জন্য একটি এপিআই এন্ডপয়েন্ট।

যদিও প্রথম প্রান্তটি ঠিক আছে তবে আমার দ্বিতীয় প্রান্তের জন্য আমি এটি কেবলমাত্র অনুমোদিত ব্যবহারকারীদের জন্যই রক্ষা করতে চাই। যার অর্থ এমন কেউ, যার টোকেন আমি আগে উত্পন্ন করেছি।

আমি কীভাবে এটি সমাধান করতে পারি?

আমি জানি আমরা ক্লাউড ফাংশনে হেডার প্যারামিটারগুলি ব্যবহার করে পেতে পারি

request.get('x-myheader')

তবে শেষ পয়েন্টটি যেমন রিয়েল টাইম ডেটা বেসকে সুরক্ষিত করার মতো কোনও উপায় আছে?



2
@ আমিনহরবাউই আমারও একই প্রশ্ন ছিল। এই পৃষ্ঠার দেখুন: firebase.google.com/docs/auth/admin/verify-id-tokens
MichM

উত্তর:


137

আপনি যা করার চেষ্টা করছেন তার জন্য একটি অফিসিয়াল কোড নমুনা রয়েছে । এটি যা চিত্রিত করে তা হ'ল কীভাবে আপনার এইচটিটিপিএস ফাংশনটি সেট আপ করবেন টোকেনের সাথে কোনও অনুমোদনের শিরোনাম প্রয়োজন যা প্রমাণীকরণের সময় ক্লায়েন্টটি পেয়েছিল। ফাংশনটি টোকেন যাচাই করতে ফায়ারবেস-অ্যাডমিন লাইব্রেরি ব্যবহার করে।

এছাড়াও, আপনার অ্যাপ্লিকেশন যদি ফায়ারবেস ক্লায়েন্ট লাইব্রেরি ব্যবহার করতে সক্ষম হয় তবে এই বয়লারপ্লেটটিকে অনেক সহজ করে তুলতে আপনি " কলযোগ্য ফাংশন " ব্যবহার করতে পারেন ।


2
এই কোড নমুনা এখনও বৈধ? আপনি কি আজকে এটি সম্বোধন করবেন এটি এখনও কি?
গাল ব্রাচা

1
@ গালব্রাচা এটি আজও বৈধ হওয়া উচিত (অক্টোবর 31 2017)।
ডগ স্টিভেনসন

@ ডগস্টেভেনসন এইসব 'কনসোল.লগ' কলগুলি কি পারফরম্যান্সে 'লক্ষণীয়' প্রভাব ফেলবে?
শঙ্কা দর্শনা

1
কলযোগ্য ফাংশনগুলি কীভাবে বয়লারপ্লেটকে সহজ করে তুলবে? এগুলি যা আমি বুঝতে পেরেছি সেগুলি কেবল "নন-রেস্ট" সার্ভার ফাংশন, তারা কীভাবে এখানে সম্পর্কিত তা আমি সত্যিই বুঝতে পারি না। ধন্যবাদ।
1252748

2
@ 1252748 আপনি লিঙ্কযুক্ত ডকুমেন্টেশনগুলি পড়লে তা পরিষ্কার হয়ে যাবে। এটি প্রমাণীকরণের টোকেনের পাসিং এবং বৈধকরণটি স্বয়ংক্রিয়ভাবে পরিচালনা করে, সুতরাং আপনাকে কোনও পাশেই সেই কোডটি লিখতে হবে না।
ডগ স্টিভেনসন

121

@ ডগ দ্বারা উল্লিখিত হিসাবে, আপনি firebase-adminএকটি টোকেন যাচাই করতে ব্যবহার করতে পারেন । আমি একটি দ্রুত উদাহরণ স্থাপন করেছি:

exports.auth = functions.https.onRequest((req, res) => {
  cors(req, res, () => {
    const tokenId = req.get('Authorization').split('Bearer ')[1];

    return admin.auth().verifyIdToken(tokenId)
      .then((decoded) => res.status(200).send(decoded))
      .catch((err) => res.status(401).send(err));
  });
});

উপরের উদাহরণে, আমি সিওআরএসও সক্ষম করেছি, তবে এটি alচ্ছিক। প্রথমত, আপনি Authorizationশিরোনামটি পান এবং এটি সন্ধান করুন token

তারপরে, আপনি firebase-adminসেই টোকেন যাচাই করতে ব্যবহার করতে পারেন । প্রতিক্রিয়াতে আপনি সেই ব্যবহারকারীর জন্য ডিকোড হওয়া তথ্য পাবেন। অন্যথায়, যদি টোকেনটি বৈধ না হয় তবে এটি একটি ত্রুটি ফেলে দেবে।


13
এটি সহজ হিসাবে উত্সাহিত, এবং সরকারী উদাহরণ যেমন মত প্রকাশের উপর নির্ভর করে না।
ডার্কনিউরন

5
আপনি কর্স সম্পর্কে আরও ব্যাখ্যা করতে পারেন?
পিট

@ পেট: কর্স কেবল ক্রস-অরিজিন রিসোর্স ভাগ করে নিচ্ছেন। আপনি এটি সম্পর্কে আরও জানতে গুগল করতে পারেন।
লং হোইং

@ পেট কর্স আপনাকে বিভিন্ন ইউআরএল থেকে সেই ফায়ারবেস-ব্যাকএন্ডের শেষ-পয়েন্টটি আঘাত করতে দেয়।
ওয়াল্টার Monecke

6
@RezaRahmati আপনি ব্যবহার করতে পারেন getIdToken()ক্লায়েন্ট-সাইড (যেমন উপর পদ্ধতি firebase.auth().currentUser.getIdToken().then(token => console.log(token))) ডক্স firebase
উইল

18

এছাড়াও @Doug উল্লেখ হিসাবে, আপনি ব্যবহার করতে পারেন Callable কার্যাবলী অনুক্রমে করার কিছু boilerplate কোড অগ্রাহ্য আপনার ক্লায়েন্ট এবং আপনার সার্ভার থেকে।

কলযোগ্য ফাংশন প্রদর্শন করুন:

export const getData = functions.https.onCall((data, context) => {
  // verify Firebase Auth ID token
  if (!context.auth) {
    return { message: 'Authentication Required!', code: 401 };
  }

  // do your things..
  const uid = context.auth.uid;
  const query = data.query;

  return { message: 'Some Data', code: 400 };
});

এটি সরাসরি আপনার ক্লায়েন্টের কাছ থেকে অনুরোধ করা যেতে পারে:

firebase.functions().httpsCallable('getData')({query}).then(result => console.log(result));

2

উপরের পদ্ধতিগুলি ফাংশনের অভ্যন্তরে যুক্তি ব্যবহার করে ব্যবহারকারীকে প্রমাণীকরণ করে , তাই ফাংশনটি এখনও চেক করতে অনুরোধ করা উচিত।

এটি সম্পূর্ণরূপে সূক্ষ্ম পদ্ধতি, তবে বোধগম্যতার জন্য একটি বিকল্প রয়েছে:

আপনি কোনও ফাংশনটিকে "ব্যক্তিগত" হিসাবে সেট করতে পারেন যাতে এটি নিবন্ধভুক্ত ব্যবহারকারীদের (আপনি অনুমতি সম্পর্কে সিদ্ধান্ত নিয়েছেন) ব্যতীত আরম্ভ করা যাবে না । এই ক্ষেত্রে, অবিশ্বস্ত অনুরোধ ফাংশন প্রেক্ষাপটে বাইরে থেকে বঞ্চিত করা হয়, এবং ফাংশন হয় না এ সব চালনা করা হয়েছে।

এখানে (ক) পাবলিক / প্রাইভেট হিসাবে ফাংশনগুলি কনফিগার করা এবং তারপরে (খ) আপনার ফাংশনগুলিতে শেষ ব্যবহারকারীদের প্রমাণীকরণ করা হবে

লক্ষ্য করুন ডক্স উপরে Google ক্লাউড প্ল্যাটফর্ম জন্য, এবং প্রকৃতপক্ষে, এই কাজ কারণ প্রত্যেক Firebase প্রকল্প এছাড়াও একটি GCP প্রকল্পের। এই পদ্ধতির সাথে সম্পর্কিত একটি সতর্কতা হ'ল লেখার মতো এটি কেবল গুগল অ্যাকাউন্ট ভিত্তিক প্রমাণীকরণের সাথে কাজ করে।


1

এক্সপ্রেস ব্যবহার করে এটিতে একটি দুর্দান্ত অফিসিয়াল উদাহরণ রয়েছে - এটি ভবিষ্যতে কার্যকর হতে পারে: https://github.com/firebase/function-sams/blob/master/authorised-https-endPoint/funitions/index.js (ঠিক নীচে আটকানো হয়েছে) অবশ্যই)

exports.appআপনার ফাংশনগুলি /appস্লাগের অধীনে উপলব্ধ করে তোলে তা মনে রাখবেন (এক্ষেত্রে কেবলমাত্র একটি ফাংশন রয়েছে এবং <you-firebase-app>/app/helloএটির অধীন উপলব্ধ । ভাল এবং মন্তব্য করার জন্য যথেষ্ট বোধগম্য ধন্যবাদ)।

/**
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
const express = require('express');
const cookieParser = require('cookie-parser')();
const cors = require('cors')({origin: true});
const app = express();

// Express middleware that validates Firebase ID Tokens passed in the Authorization HTTP header.
// The Firebase ID token needs to be passed as a Bearer token in the Authorization HTTP header like this:
// `Authorization: Bearer <Firebase ID Token>`.
// when decoded successfully, the ID Token content will be added as `req.user`.
const validateFirebaseIdToken = async (req, res, next) => {
  console.log('Check if request is authorized with Firebase ID token');

  if ((!req.headers.authorization || !req.headers.authorization.startsWith('Bearer ')) &&
      !(req.cookies && req.cookies.__session)) {
    console.error('No Firebase ID token was passed as a Bearer token in the Authorization header.',
        'Make sure you authorize your request by providing the following HTTP header:',
        'Authorization: Bearer <Firebase ID Token>',
        'or by passing a "__session" cookie.');
    res.status(403).send('Unauthorized');
    return;
  }

  let idToken;
  if (req.headers.authorization && req.headers.authorization.startsWith('Bearer ')) {
    console.log('Found "Authorization" header');
    // Read the ID Token from the Authorization header.
    idToken = req.headers.authorization.split('Bearer ')[1];
  } else if(req.cookies) {
    console.log('Found "__session" cookie');
    // Read the ID Token from cookie.
    idToken = req.cookies.__session;
  } else {
    // No cookie
    res.status(403).send('Unauthorized');
    return;
  }

  try {
    const decodedIdToken = await admin.auth().verifyIdToken(idToken);
    console.log('ID Token correctly decoded', decodedIdToken);
    req.user = decodedIdToken;
    next();
    return;
  } catch (error) {
    console.error('Error while verifying Firebase ID token:', error);
    res.status(403).send('Unauthorized');
    return;
  }
};

app.use(cors);
app.use(cookieParser);
app.use(validateFirebaseIdToken);
app.get('/hello', (req, res) => {
  res.send(`Hello ${req.user.name}`);
});

// This HTTPS endpoint can only be accessed by your Firebase Users.
// Requests need to be authorized by providing an `Authorization` HTTP header
// with value `Bearer <Firebase ID Token>`.
exports.app = functions.https.onRequest(app);

পরিত্রাণ পেতে আমার পুনর্লিখন /app:

const hello = functions.https.onRequest((request, response) => {
  res.send(`Hello ${req.user.name}`);
})

module.exports = {
  hello
}

0

আমি গোলং জিসিপি ফাংশনে যথাযথ ফায়ারবেস প্রমাণীকরণ পেতে সংগ্রাম করে যাচ্ছি। আসলে এর উদাহরণ নেই, তাই আমি এই ক্ষুদ্র গ্রন্থাগারটি তৈরির সিদ্ধান্ত নিয়েছি: https://github.com/Jblew/go-firebase-auth-in-gcp-funtions

এখন আপনি সহজেই ফায়ারবেস-প্রমাণ ব্যবহার করে ব্যবহারকারীদের প্রমাণীকরণ করতে পারেন (যা জিসিপি-প্রমাণীকরণযোগ্য-ফাংশন থেকে পৃথক এবং পরিচয়-সচেতন-প্রক্সি দ্বারা সরাসরি সমর্থিত নয়)।

ইউটিলিটি ব্যবহারের উদাহরণ এখানে:

import (
  firebaseGcpAuth "github.com/Jblew/go-firebase-auth-in-gcp-functions"
  auth "firebase.google.com/go/auth"
)

func SomeGCPHttpCloudFunction(w http.ResponseWriter, req *http.Request) error {
   // You need to provide 1. Context, 2. request, 3. firebase auth client
  var client *auth.Client
    firebaseUser, err := firebaseGcpAuth.AuthenticateFirebaseUser(context.Background(), req, authClient)
    if err != nil {
    return err // Error if not authenticated or bearer token invalid
  }

  // Returned value: *auth.UserRecord
}

--allow-unauthenticatedফ্ল্যাগ দিয়ে আপনাকে ফাংশন মোতায়েনের জন্য কেবল মনে রাখবেন (কারণ ফাংশন সম্পাদনের অভ্যন্তরে ফায়ারবেস প্রমাণীকরণ ঘটে)।

আশা করি এটি যেমন আপনাকে সহায়তা করেছিল তেমন আপনাকে সহায়তা করবে। পারফরম্যান্সের কারণে মেঘ ফাংশনগুলির জন্য গোলং ব্যবহার করতে আমি দৃ determined় প্রতিজ্ঞ ছিল - যাদ্রজেজ


0

ফায়ারবেসে, আপনার কোড এবং আপনার কাজকে সহজ করার জন্য, এটি কেবল স্থাপত্য নকশার বিষয় :

  1. সর্বজনীন অ্যাক্সেসযোগ্য সাইট / সামগ্রীগুলির জন্য , HTTPS এর সাথে ট্রিগারExpress ব্যবহার করুন । কেবলমাত্র একই সাইট বা নির্দিষ্ট সাইটকে সীমাবদ্ধ করতে CORS, সুরক্ষার এই দিকটি নিয়ন্ত্রণ করতে ব্যবহার করুন । এটি Expressসার্চ-সাইড রেন্ডারিং সামগ্রীর কারণে SEO এর জন্য দরকারী কারণ এটি বোধগম্য ।
  2. যে অ্যাপগুলিতে ব্যবহারকারীর অনুমোদনের প্রয়োজন রয়েছে তাদের জন্য , HTTPS কলযোগ্য ফায়ারবেস ফাংশনগুলি ব্যবহার করুন, তারপরে contextসমস্ত ঝামেলাগুলি সংরক্ষণ করতে প্যারামিটারটি ব্যবহার করুন । এটিও অর্থবোধ করে, কারণ অ্যাঙ্গুলারজেএস দিয়ে তৈরি একটি সিঙ্গল পেজ অ্যাপ্লিকেশন হিসাবে - অ্যাঙ্গুলারজেএস এসইও এর পক্ষে খারাপ তবে এটি একটি পাসওয়ার্ড সুরক্ষিত অ্যাপ্লিকেশন হওয়ায় আপনার এসইওর খুব বেশি প্রয়োজন নেই। টেম্পলেট করার ক্ষেত্রে, AngularJS এর ​​অন্তর্নির্মিত টেম্প্লেটিং রয়েছে, সুতরাং সেভ-সাইড টেম্পলেটটির প্রয়োজন নেই Express। তারপরে ফায়ারবেস কলযোগ্য ফাংশনগুলি যথেষ্ট ভাল হওয়া উচিত।

উপরের কথা মাথায় রেখে আর ঝামেলা করবেন না এবং জীবনকে সহজ করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.