我是网络开发新手,开始学习 ReactJS。
到目前为止,构建简单的网络应用程序没有问题。
现在我想使用 Firebase 进行身份验证。
我知道如何使用 Firebase 对用户进行身份验证,但我不知道如何设计前端来限制对某些页面的访问。
以前,我使用 PHP,其中我使用 session
变量和 include
来包含要显示给用户的 HTML 部分。
但我不知道如何使用 Firebase 在 ReactJS 中执行此操作。
初始和失败的方法:
我想更新 this.state.loggedIn
并使用它来显示组件。但这不是正确的方法,因为我发送了两个组件来显示,并且我们可以使用 Chrome 中的 React 开发人员扩展轻松更改组件的状态。
这是我的主要 index.js 代码:
import React from 'react';
import ReactDOM from 'react-dom';
import Login from './components/Login/Login';
import Home from './components/Home/Home';
import fire from './components/Fire';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
loggedIn: false,
};
this.authListener = this.authListener.bind(this);
}
componentDidMount() {
this.authListener();
}
authListener() {
fire.auth().onAuthStateChanged(user => {
if (user) {
// User is signed in.
console.log(user);
this.setState({
loggedIn: true
})
} else {
// No user is signed in.
this.setState({
loggedIn: false
});
}
});
}
render() {
return (
<div>
{this.state.loggedIn ? <Home/> : <Login/>}
</div>
);
}
}
ReactDOM.render(
<App/>, document.getElementById('app'));
在 Login.js 中,我调用了 Firebase 身份验证函数。
只是片段:
fire
.auth()
.signInWithEmailAndPassword(this.state.email, this.state.password)
.catch(function (error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
console.log(error);
// ...
});
身份验证工作正常,我可以在控制台日志中看到它。
那么,我应该如何在 ReactJS + Firebase 中进行身份验证?(是否可以不使用任何其他包,如 react-routes 等?)
或者我应该为此使用云功能吗?
最佳答案
更新:
您在 html 文件中链接的所有内容都应始终来自您的公共(public)目录。因此,请将捆绑的 .js
文件保存在公共(public)目录中。
我已经为初学者写了一些节省时间的技巧。您可以找到更多关于初学者的提示 here .
其实很简单
如果您只想向浏览器发送所需的 html 文件,则每次需要一个完全不同的 html 时都必须访问服务器。
你说你用的是PHP。在 PHP 中,我们使用 session 来了解一个人是否登录。
所以,我们尝试在这里实现它。
首先让我们看看 PHP 中的 session 是如何工作的。取自 SO Answer
In the general situation :
- the session id is sent to the user when his session is created.
- it is stored in a cookie (called, by default,
PHPSESSID
)- that cookie is sent by the browser to the server with each request
- the server (PHP) uses that cookie, containing the session_id, to know which file corresponds to that user.
The data in the sessions files is the content of
$_SESSION
, serialized (ie, represented as a string -- with a function such as serialize) ; and is un-serialized when the file is loaded by PHP, to populate the$_SESSION
array.
Sometimes, the session id is not stored in a cookie, but sent in URLs, too -- but that's quite rare, nowadays.
For more informations, you can take a look at the Session Handling section of the manual, that gives some useful informations.For instance, there is a page about Passing the Session ID, which explains how the session id is passed from page to page, using a cookie, or in URLs -- and which configuration options affect this.
因此,session
只是一个 cookie。那么我想我们可以使用 cookie 来了解用户登录状态。
在 Firebase 中,cookie 存在问题。您只能将 cookie 名称设置为 __session
。 Firebase 会忽略其他名称,因此您无法读取服务器上的 cookie。
您需要使用 Firebase Functions 来做一些后端工作,并根据用户登录状态提供 html。
因此,在您的项目目录中设置 Firebase Functions。在根中,
$ firebase init functions
现在您必须告诉 Firebase,任何到达您域的请求都必须调用一个函数。
为此,您必须在 firebase.json
文件中编写 rewrites
。我们的函数名称将是 main
。
{
"database": {
"rules": "database.rules.json"
},
"hosting": {
"public": "/dev",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites":[{
"source": "**",
"function": "main"
}]
}
}
现在在任何地方创建一个 index.js
(首选项目目录的根目录,因为这是主文件)。
index.js
import express from 'express';
import * as functions from 'firebase-functions';
import fs from 'fs';
var cookieParser = require('cookie-parser')
const app = express();
app.use(cookieParser());
app.get('**', (req, res) => {
// Check the custom set cookie for user
// If the user is not logged-in, redirect to Login. Otherwise, redirect to Home page
if (req.cookies.__session == 'loggedin') {
var index = fs.readFileSync(__dirname + '/src/Home/index.html', 'utf8');
}
else {
var index = fs.readFileSync(__dirname + '/src/Login/index.html', 'utf8');
}
res.send(index);
});
export let main = functions.https.onRequest(app);
关于以上部分的一些解释:
express
:用于处理请求和发送响应。firebase-functions
:由Google提供,用于使用Firebase Functions。fs
: 我们根据用户登录状态从文件系统中读取合适的html并提供。cookie-parser
:我们用它来轻松访问我们的 cookie。
注意:您需要将其转换为 ES5。所以使用 babel 命令来转换它(我假设你在根目录中保存了 index.js
。)
$ babel index.js -d functions
我们使用名为 __session
的 cookie 来了解用户登录状态。
如果 __session
设置为 loggedin
,我们将向用户发送 Home
html
。否则,我们发送 Login
html
。
现在,真正的问题是:“我们需要在哪里设置 cookie __session
?”
我们在用户浏览器中设置 cookie。
我们使用 onAuthStateChanged()
。
在您的登录页面组件
中调用此方法,例如:
componentDidMount() {
this.authListener();
}
authListener() {
fire.auth().onAuthStateChanged(user => {
if (user) {
// User is signed in.
if (Cookies.get('__session') === undefined) {
Cookies.set('__session', 'loggedin', { expires: 3652 });
window.location.reload();
}
} else {
// No user is signed in.
Cookies.remove('__session');
}
});
}
注意:Cookies
对象是从 js-cookie 导入的.所以,安装它。
我们在这里做的是:
首先在页面加载时调用
onAuthStateChanged()
。如果用户已经登录,我们进入
if
block 。然后我们检查
__session
cookie。这很重要,因为有时用户可以清除所有 cookie。当我们尝试读取服务器中的 cookie 时,我们得到undefined
并将登录页面发送给用户。从1
开始重复该过程。然后我们重新加载页面。当我们重新加载页面时,用户再次访问服务器。然后我们可以检查
__session
cookie 并将Home
html
发送给用户。
关于javascript - 使用 ReactJS 和 Firebase 进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51064424/