web-dev-qa-db-ja.com

クライアント側の認証なしでサーバーからFirebaseユーザーを認証する方法は?

Node adminsdkを使用してfirebaseに接続して呼び出すAPIがあります。私のクライアントは、必要なすべてのものについて私のAPIをヒットしました。クライアントコードをAPIとバックエンドから切り離したいので、直接認証するためにFirebaseを呼び出す必要はありません。

サーバーはどのようにそれらを認証できますか?現在のドキュメントに基づいて、少なくともクライアントはAPIにuidを提供する必要があります(これは、自分で認証されていることを前提としていますよね?)。

理想的には、クライアントはPOST over ssl over sslの本文でユーザー名とパスワードを私のAPIに提供し、APIはそれらをログインして、IDトークンを送り返します。推奨される方法は何ですか。これを行う?

6
Brian

更新を提供したかっただけです:文書化されていないREST APIはここにあります: Firebase RESTノードでトークンを作成するときの認証.js admin sdk

できれば、これを答えとしてマークします。

7
Brian

認証にFirebaseを使用する場合は、クライアントSDKによってクライアント側で処理するのが最適です。これは、認証がIPアドレスに基づいてレート制限されており、セッション管理と永続性のコーディングプロセスをスキップできるためです。

ただし、サーバーでクライアントSDKをホストし、リクエストをFirebaseにハンドボールすることで、ログイン/ユーザーの数が少ないと予想される場合は、目的を達成できます。

// app.js

const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const express = require('express');
const firebase = require('firebase'); // client SDK

firebase.initializeApp({
  apiKey: "<API_KEY>",
  authDomain: "<PROJECT_ID>.firebaseapp.com"
});

const app = express();
app.use(bodyParser.json());
app.use(cookieParser(['array', 'of', 'secrets']));

// on future requests, the UID can be found using `req.cookies['__session'].uid`

app.post('/login', function (req, res, next) {
  if (!req.body.email) return res.status(400).json({error: 'missing email'});
  if (!req.body.password) return res.status(400).json({error: 'missing password'});

  firebase.auth().setPersistence(firebase.auth.Auth.Persistence.NONE) // don't persist auth session
  .then(function() {
    return firebase.auth().signInWithEmailAndPassword(req.body.email, req.body.password)
  });
  .then((user) => { // https://firebase.google.com/docs/reference/js/firebase.User
    let uid = user.uid;

    // set cookie with UID or some other form of persistence
    // such as the Authorization header
    res.cookie('__session', { uid: uid }, { signed: true, maxAge: 3600 });
    res.set('cache-control', 'max-age=0, private') // may not be needed. Good to have if behind a CDN.
    res.send('You have successfully logged in');

    return firebase.auth().signOut(); //clears session from memory
  })
  .catch((err) => {
    next(err);
  });
});

module.exports = app;

注:クラウド関数 を使用してAPIを同じ場所に配置することも検討してください。ユースケースによっては、これが費用効果の高いオプションになる場合があります。

7
samthecodingman