ssh*_*ssh 5 javascript authentication firebase reactjs firebase-authentication
我是 Web 开发的新手,并开始学习 ReactJS。
到目前为止,构建简单的 Web 应用程序没有问题。
现在我想使用 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'));
Run Code Online (Sandbox Code Playgroud)
在 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);
// ...
});
Run Code Online (Sandbox Code Playgroud)
身份验证工作正常,我可以在控制台日志中看到它。
那么,我应该如何在 ReactJS + Firebase 中进行身份验证?(是否可以不使用任何其他包,如 react-routes 等?)
或者我应该为此使用云函数?
更新:
您在 html 文件中链接的所有内容都应始终来自您的公共目录。因此,请将捆绑.js
文件保存在公共目录中。
我为初学者写了一些节省时间的技巧。您可以在此处找到有关初学者技巧的更多信息。
其实很简单。
如果您只想将所需的 html 文件发送到浏览器,则每次需要完全不同的 html 时都必须访问服务器。
你说你用的是PHP。在 PHP 中,我们使用会话来了解一个人是否登录。
所以,我们尝试在这里实现它。
首先让我们看看 PHP 中的会话是如何工作的。摘自SO 答案
在一般情况下:
- 创建会话时,会话 ID 会发送给用户。
- 它存储在 cookie 中(默认情况下称为
PHPSESSID
)- 该 cookie 由浏览器在每次请求时发送到服务器
- 服务器 (PHP) 使用包含 session_id 的 cookie 来了解哪个文件对应于该用户。
会话文件中的数据是
$_SESSION
序列化的内容(即表示为字符串 - 使用序列化等函数 );当 PHP 加载文件时,它会被取消序列化,以填充数组$_SESSION
。
有时,会话 ID 不存储在 cookie 中,而是以 URL 形式发送——但现在这种情况很少见。
有关更多信息,您可以查看手册的会话处理部分,其中提供了一些有用的信息。例如,有一个关于传递会话 ID 的页面,它解释了如何使用 cookie 或在 URL 中从一个页面传递到另一个页面的会话 ID,以及哪些配置选项会影响它。
所以,session
只是一块饼干。那么我想我们可以使用cookie来了解用户的登录状态。
在 Firebase 中,cookie 存在问题。您只能将 cookie 名称设置为__session
。Firebase 会忽略其他名称,因此您无法读取服务器上的 cookie。
您需要使用 Firebase Functions 执行一些后端工作并根据用户登录状态提供 html。
因此,在您的项目目录中设置 Firebase 函数。在根部,
$ firebase init functions
Run Code Online (Sandbox Code Playgroud)
现在您必须对 Firebase 说,任何传入您域的请求都必须调用一个函数。
为此,您必须rewrites
在firebase.json
文件中写入。我们的函数名称将是main
.
{
"database": {
"rules": "database.rules.json"
},
"hosting": {
"public": "/dev",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites":[{
"source": "**",
"function": "main"
}]
}
}
Run Code Online (Sandbox Code Playgroud)
现在在任何地方创建一个index.js
(最好是项目目录的根目录,因为这是主文件)。
索引.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);
Run Code Online (Sandbox Code Playgroud)
对以上部分的一些解释:
express
:用于处理请求并发送响应。
firebase-functions
:由 Google 提供,用于使用 Firebase Functions。
fs
:我们根据用户登录状态从文件系统读取适当的html并提供服务。
cookie-parser
:我们用它来轻松访问我们的 cookie。
注意:您需要将其转换为 ES5。所以使用 babel 命令来转换它(我假设你保存index.js
在你的根目录中。)
$ babel index.js -d functions
Run Code Online (Sandbox Code Playgroud)
我们使用名为 cookie__session
来了解用户登录状态。
如果__session
设置为loggedin
,我们将发送给用户Home
html
。否则,我们发送Login
html
.
现在,真正的问题是:“我们需要在哪里设置 cookie __session
?”
我们在用户浏览器中设置 cookie。
我们利用onAuthStateChanged()
.
按照您的Login page component
喜好调用此方法:
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');
}
});
}
Run Code Online (Sandbox Code Playgroud)
注意:Cookies
对象是从js-cookie导入的。所以,安装它。
我们在这里所做的是:
首先,onAuthStateChanged()
在页面加载时首先调用 。
如果用户已经登录,我们就进入if
块。
然后我们检查__session
cookie。这很重要,因为有时用户可以清除所有 cookie。当我们尝试读取服务器中的 cookie 时,我们会获取undefined
登录页面并将其发送给用户。重复该过程1
。
然后我们重新加载页面。当我们重新加载页面时,用户再次访问服务器。然后我们可以检查__session
cookie 并将其发送Home
html
给用户。
归档时间: |
|
查看次数: |
2807 次 |
最近记录: |