У меня есть веб-приложение, созданное с помощью Gatsby, которое имеет аутентификацию на стороне клиента через Auth0.Я хочу использовать Firebase в качестве базы данных для моего проекта, но мне нужно сначала проверить подлинность пользователей, прежде чем они смогут читать / писать в Firebase.
В Firebase SDK (firebase-admin) есть функция signInWithCustomToken (токен), в которую, как я думал, можно передать токен из Auth0, но это не сработает (см .: https://community.auth0.com/t/react-auth0-firebase/11392).
Вместо этого мне нужно прокси-токен Auth0 через API, который будет использовать firebase-admin для выдачи токена.Так как мой сайт Gatsby размещен на Netlify, я планирую использовать функции Netlify Lambda для получения токена Auth0-токенаВот где я застреваю.
Я следовал этому руководству по использованию лямбда-функций Netlify с Gastsby: https://www.gatsbyjs.org/blog/2018-12-17-turning-the-static-dynamic/
Затем я вошел в свой файл Auth.jsгде мой код Auth0 и отбросил вызов извлечения в setSession. Я передал idToken из Auth0 в URL в функции извлечения. Я не уверен, что это правильно, я прочитал в учебнике, чтоэто будет передано в заголовке авторизации, но мне неясно, что это значит. В любом случае, вот полный файл auth.js:
import auth0 from 'auth0-js';
const windowGlobal = typeof window !== 'undefined' && window;
class Auth {
auth0 = new auth0.WebAuth({
domain: process.env.Auth_Domain,
clientID: process.env.Auth_ClientId,
redirectUri: process.env.Auth_Callback,
responseType: 'token id_token',
scope: 'openid profile email',
});
constructor() {
this.login = this.login.bind(this);
this.logout = this.logout.bind(this);
this.handleAuthentication = this.handleAuthentication.bind(this);
this.isAuthenticated = this.isAuthenticated.bind(this);
}
login() {
this.auth0.authorize();
}
logout() {
// Remove the locally cached profile to avoid confusing errors.
localStorage.removeItem('access_token');
localStorage.removeItem('id_token');
localStorage.removeItem('expires_at');
localStorage.removeItem('user');
windowGlobal.window.location.replace(`https://login.skillthrive.com/v2/logout/?returnTo=http%3A%2F%2Flocalhost:8000`)
}
handleAuthentication() {
if (typeof window !== 'undefined') {
this.auth0.parseHash((err, authResult) => {
if (authResult && authResult.accessToken && authResult.idToken) {
this.setSession(authResult)
} else if (err) {
console.log(err);
}
});
}
}
isAuthenticated() {
const expiresAt = JSON.parse(localStorage.getItem('expires_at'));
return new Date().getTime() < expiresAt;
}
setSession(authResult) {
const expiresAt = JSON.stringify((authResult.expiresIn * 1000) + new Date().getTime());
localStorage.setItem('access_token', authResult.accessToken);
localStorage.setItem('id_token', authResult.idToken);
localStorage.setItem('expires_at', expiresAt);
fetch(`/.netlify/functions/firebase?id=${authResult.idToken}`)
.then(response => console.log(response))
this.auth0.client.userInfo(authResult.accessToken, (err, user) => {
localStorage.setItem('user', JSON.stringify(user));
})
}
getUser() {
if (localStorage.getItem('user')) {
return JSON.parse(localStorage.getItem('user'));
}
}
getUserName() {
if (this.getUser()) {
return this.getUser().name;
}
}
}
export default Auth;
Я нашел учебник под названием Как Aпротестировать Firebase и Angular с помощью Auth0 , который имеет функцию, которая генерирует токен для Firebase:
const jwt = require('express-jwt');
const jwks = require('jwks-rsa');
const firebaseAdmin = require('firebase-admin');
// Config
const config = require('./config');
module.exports = function(app) {
// Auth0 athentication middleware
const jwtCheck = jwt({
secret: jwks.expressJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: `https://${config.AUTH0_DOMAIN}/.well-known/jwks.json`
}),
audience: config.AUTH0_API_AUDIENCE,
issuer: `https://${config.AUTH0_DOMAIN}/`,
algorithm: 'RS256'
});
// Initialize Firebase Admin with service account
const serviceAccount = require(config.FIREBASE_KEY);
firebaseAdmin.initializeApp({
credential: firebaseAdmin.credential.cert(serviceAccount),
databaseURL: config.FIREBASE_DB
});
app.get('/auth/firebase', jwtCheck, (req, res) => {
// Create UID from authenticated Auth0 user
const uid = req.user.sub;
// Mint token using Firebase Admin SDK
firebaseAdmin.auth().createCustomToken(uid)
.then(customToken =>
// Response must be an object or Firebase errors
res.json({firebaseToken: customToken})
)
.catch(err =>
res.status(500).send({
message: 'Something went wrong acquiring a Firebase token.',
error: err
})
);
});
Я пытался одновременно включать небольшие детали в свою функцию Lambda:
var admin = require("firebase-admin");
const jwt = require('express-jwt');
const jwks = require('jwks-rsa');
// For more info, check https://www.netlify.com/docs/functions/#javascript-lambda-functions
export function handler(event, context, callback) {
console.log("queryStringParameters", event.queryStringParameters);
const jwtCheck = jwt({
secret: jwks.expressJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: `https://${process.env.Auth_Domain}/.well-known/jwks.json`
}),
audience: process.env.Auth_Audience,
issuer: `https://${process.env.Auth_Domain}/`,
algorithm: 'RS256'
});
callback(null, {
// return null to show no errors
statusCode: 200, // http status code
body: JSON.stringify({
msg: "Hello, World! " + Math.round(Math.random() * 10),
}),
})
}
Я попытался проверить, что за jwtCheck вернул консоль, зарегистрировав его, но все, что я получил, было что-то странное { [Function: d] unless: [Function], UnauthorizedError: [Function: r] }
Как мне включить это в мою функцию Lambda?