如何在 Firebase 对用户进行身份验证后从服务器端重定向浏览器



我在Firebase上托管了一个node.jsexpress.js应用程序。它托管在 : https://spice-ai.firebaseapp.com/

我想在用户身份验证后重定向到其他页面。但是,res.redirect('/user')仅在app.get上重定向,而不是app.post。这很奇怪,有人可以告诉我为什么吗?

我的index.ts

import * as express   from 'express'           ;
import * as admin     from 'firebase-admin'    ;
import * as functions from 'firebase-functions';
import * as path      from "path"              ;
import * as math      from 'mathjs'            ;

import { Option, some, none } from 'fp-ts/lib/Option';
import * as bodyParser            from "body-parser";
import { body, validationResult } from 'express-validator/check';
import { sanitizeBody }           from 'express-validator/filter';

const accountKeyPath = path.join(__dirname, '../credentials/serviceAccountKey.json');
const accountKey     = require(accountKeyPath);
const adminSDKPath   = path.join(__dirname, '../credentials/spice-ai-firebase-adminsdk.json');
const adminSDK       = require(adminSDKPath);
const firebaseAdmin = admin.initializeApp({
credential : admin.credential.cert(adminSDK)
, databaseURL: accountKey['databaseURL']
});
const dbRef = new Proposal(firebaseAdmin, 'datasets');
const auth  = firebaseAdmin.auth()

// create HTTP server
const app = express();

// use json form parser middleware
app.use(bodyParser.json());
// use query string parser middlware
app.use(bodyParser.urlencoded({ extended: true }));
// set view engine
app.set('views', path.join(__dirname, '../src/view'))
app.set('view engine', 'pug');
// set static file source
app.use(express.static(path.join(__dirname, "../public")));
app.use(cors({origin: 'http://localhost:5000'}));
app.use(cors({origin: '/'}    ));
app.use(cors({origin: '/user'}));

app.get('/', (req,res) => {
res.render('pages/login', {})
// a res.redirect('/user') redirects immediately here
});

app.post('/', (req, res) => {
// this does not redirect
console.log('n+++++++++++++++++++++++++++ POST')
res.redirect('/user');
})
app.get('/user' , (req, res) => {
console.log('n############################### GET /user')
res.render('pages/user')
});
exports.app = functions.https.onRequest(app);

前端上postjson的相应app.js

const config = {
"apiKey"           : ""
"authDomain"       : ""
"databaseURL"      : ""
"projectId"        : ""
"storageBucket"    : ""
"messagingSenderId": ""
};

firebase.initializeApp(config);
const auth = firebase.auth(); 
auth.onAuthStateChanged(user => {
if (user) {
console.log("loaded page with user: ", user['email'])
user.getIdToken(true)
.then( idToken => {
console.log('user token: ', idToken)
post_utoken(idToken);
})
} else {
console.log('no user found')
}
});

/**
@Use: send user id to server
*/
function post_utoken(tok){
var data = {};
data.userToken = tok
$.ajax({
type        : 'POST'
, url         : 'http://localhost:5000/'
, data        : data
, dataType    : 'json'
, success : function(data) {
console.log('n======================================')
console.log('success sending data from app.js')
}
})
}

一切都很标准。此外,在我的bash上,我可以看到重定向和app.get('/user' ..)都已触发,因为我有:

++++++++++++++++++++++++++ POST
info: Execution took 1 ms, user function completed successfully
127.0.0.1 - - [31/May/2018:22:03:28 +0000] "POST / HTTP/1.1" 302 27 "http://localhost:5000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"
[hosting] Rewriting /user to local function app
info: User function triggered, starting execution
info: 
############################### GET /user
info: Execution took 78 ms, user function completed successfully
127.0.0.1 - - [31/May/2018:22:03:28 +0000] "GET /user HTTP/1.1" 200 6547 "http://localhost:5000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36"

然而,在客户端,即使app.get('/user'...)已经解雇,我仍然处于localhost:5000

====

====================================================================编辑:

我看到在发布到服务器时ajax在做什么存在概念上的误解。我想将所有应用程序状态集中在服务器端,因此如果可能的话,我想redirectapp.get('/' ..)回调中/user。因此,这意味着客户端没有ajax,如果是这样,我将如何将信息发送到服务器端?我可以用socket.io来做还是过度设计?如果是这样,我该怎么办?

同样,我必须从服务器端重定向,因为我使用 index.ts 作为我的应用控制器,所以我根本不希望在客户端使用状态更改逻辑,除非由于 firebase 约束而进行用户身份验证。

你的期望有点偏离。

当服务器使用 HTTP 状态代码 302 响应时,它会告诉浏览器下一步要去哪里,这在使用GET请求进行导航时是有意义的,而在通过 ajax 发布数据时则不那么有意义,您可以在其中完全控制接下来发生的事情。

实际上更容易,尝试这样的事情:

success : function(data) {
window.location.href = '/user'
}

这正是您所期望的,在客户端完成。

如果你真的需要在服务器端完成它,那么添加一个html表单并通过javascript提交它,这样浏览器将处理请求并采取适当的操作。

将此添加到您的 HTML 中:

<form id="userform" action="/" method="POST" style="display: none">
<input id="userform_email" name="email" value="">
</form>

然后在您的脚本中:

auth.onAuthStateChanged(user => {
if (user) {
document.getElementById('userform_email').value = user['email'];
document.getElementById('userform').submit();
} else {
console.log('no user found')
}
});

您正在做的是创建一个不可见的表单,一旦Firebase完成其操作,该表单就会提交。数据将以不同的形式到达服务器,因此您可能需要在那里进行一些调整。

相关内容

最新更新