Javascript 使用ReactJS和Firebase进行身份验证
我刚接触web开发,开始学习ReactJS 到目前为止,构建简单的web应用程序没有问题 现在我想使用Firebase进行身份验证 我知道如何使用Firebase对用户进行身份验证,但我不知道如何设计前端来限制对某些页面的访问 之前,我使用了PHP,其中我使用了Javascript 使用ReactJS和Firebase进行身份验证,javascript,reactjs,firebase,authentication,firebase-authentication,Javascript,Reactjs,Firebase,Authentication,Firebase Authentication,我刚接触web开发,开始学习ReactJS 到目前为止,构建简单的web应用程序没有问题 现在我想使用Firebase进行身份验证 我知道如何使用Firebase对用户进行身份验证,但我不知道如何设计前端来限制对某些页面的访问 之前,我使用了PHP,其中我使用了session变量和include来包含要显示给用户的HTML部分 但我不知道如何使用Firebase在ReactJS中实现这一点 初始和失败的进近: import React from 'react'; import ReactDOM
session
变量和include
来包含要显示给用户的HTML部分
但我不知道如何使用Firebase在ReactJS中实现这一点
初始和失败的进近:
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'));
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);
// ...
});
我想更新this.state.loggedIn
并用它来显示组件。但这不是一种正确的方式,因为我将两个组件都发送到显示器上,我们可以使用Chrome中的React developer extension轻松地更改组件的状态
这是我的主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'));
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等?)
或者我应该为此使用云函数吗
在此之前,我使用了PHP,其中我使用了session变量和include来包含要向用户显示的HTML部分
Firebase有多种方式保持其身份验证状态,如下所述:
默认情况下,它是local
。在Web上,这是localStorage
。这对您来说可能是一个巨大的变化,因为通常身份验证状态是在服务器端和客户端完成的某种会话或cookie中
那么,我应该如何在ReactJS+Firebase中进行身份验证?(是否可以不使用任何其他包,如react-routes等?)
但使用Firebase,一切都是在客户端完成的。用户成功进行身份验证后,您将有权访问其身份验证令牌,如下所述:
使用此令牌,您需要在服务器端进行如下验证:以保护/保护任何API访问
但是为了保护React应用程序中的某些页面,您需要在某种中间件中验证localStorage
中的身份验证状态。最好在React生命周期方法之一中有一个身份验证状态的侦听器:
在应用程序中的任何时候,身份验证状态都将变为无效,请阻止他们查看页面。好的,我将向您展示如何在React应用程序上使用firebase auth。我只是想让你知道这不是正确的方法,你会找到很多方法 让我们开始吧,首先我使用Google Auth,我有一个名为
firebase.service.js
的文件,在这里我处理Auth。该文件看起来像:
import firebase from 'firebase';
import { firebaseConfig } from './private';
export const firebaseApp = firebase.initializeApp(firebaseConfig);
export const auth = firebase.auth();
export const db = firebase.database();
export function loginGoogle(/* options */) {
const provider = new firebase.auth.GoogleAuthProvider();
return firebase.auth().signInWithPopup(provider);
}
import React from 'react';
import ReactDOM from 'react-dom';
import firebase from 'firebase';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { auth } from './services';
auth.setPersistence(firebase.auth.Auth.Persistence.LOCAL).then(() => {
const stop = auth.onAuthStateChanged(() => {
ReactDOM.render(<App />, document.getElementById('root'));
stop();
});
});
registerServiceWorker();
firebaseConfig
对象如下所示:
const firebaseConfig = {
apiKey: API_KEY,
authDomain: AUTH_DOMAIN,
databaseURL: DB_URL,
projectId: PROJECT_ID,
storageBucket: STORE_BUCKET,
messagingSenderId: MSG_SENDER,
};
您可以在Firebase控制台上找到它
在安装该应用程序的索引文件处,我使用身份验证检查包装了ReactDOM.render
方法,以确保用户是否登录。该索引如下所示:
import firebase from 'firebase';
import { firebaseConfig } from './private';
export const firebaseApp = firebase.initializeApp(firebaseConfig);
export const auth = firebase.auth();
export const db = firebase.database();
export function loginGoogle(/* options */) {
const provider = new firebase.auth.GoogleAuthProvider();
return firebase.auth().signInWithPopup(provider);
}
import React from 'react';
import ReactDOM from 'react-dom';
import firebase from 'firebase';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { auth } from './services';
auth.setPersistence(firebase.auth.Auth.Persistence.LOCAL).then(() => {
const stop = auth.onAuthStateChanged(() => {
ReactDOM.render(<App />, document.getElementById('root'));
stop();
});
});
registerServiceWorker();
在这里,您可以看到该函数检查是否存在任何已登录的用户,否则它会将用户发送回根路径。请注意,我正在从/services
导入auth
,而不是从firebase
导入,这是因为此auth是在firebase.service.js
处初始化的,然后我通过所有应用程序使用它
现在您可以将此PrivateRoute
用作公共路由,区别在于将检查用户是否已登录。以此为例:
import * as React from 'react';
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom';
import { Layout } from 'antd';
import moment from 'moment';
import 'moment/locale/pt-br';
import 'antd/dist/antd.css';
import { PrivateRoute, MainLogged, Login, Navbar, Page404 } from './components';
const { Header } = Layout;
moment.locale('pt-br');
function Main() {
return <Redirect to="/login" />;
}
function App() {
return (
<BrowserRouter>
<Layout>
<Header style={{ paddingLeft: '0', backgroundColor: '#096dd9' }}>
<Navbar />
</Header>
<Switch>
<Route exact path="/" component={Main} />
<Route exact path="/login" component={Login} />
<PrivateRoute path="/app" component={MainLogged} />
<Route component={Page404} />
</Switch>
</Layout>
</BrowserRouter>
);
}
export default App;
import*as React from'React';
从“react router dom”导入{BrowserRouter,Route,Switch,Redirect};
从“antd”导入{Layout};
从“力矩”中导入力矩;
导入“时刻/地点/pt br”;
导入“antd/dist/antd.css”;
从“/components”导入{PrivateRoute,MainLogged,Login,Navbar,Page404};
const{Header}=布局;
地点(“pt-br”);
函数Main(){
返回;
}
函数App(){
返回(
);
}
导出默认应用程序;
如您所见,PrivateRouse
与react路由器的Route
组件并排使用
我想这就是全部,如果你想问任何其他问题,请发表评论,如果你想看看我从哪里获取这些代码的项目,你可以找到它。更新:
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'));
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);
// ...
});
html文件中链接的所有内容都应该始终来自公共目录。因此,将捆绑的.js
文件保存在公共目录中
我为初学者写了一些节省时间的小贴士。你可以找到更多关于初学者的提示
其实很简单
如果只想将所需的html文件发送到浏览器,则每次需要完全不同的html时,都必须点击服务器
你说你用的是PHP。在PHP中,我们使用会话来了解一个人是否登录
所以,我们尝试在这里实现它
首先让我们看看PHP中的会话是如何工作的。摘自
在一般情况下:
- 会话id在用户创建会话时发送给用户
- 它存储在cookie中(默认情况下称为
PHPSESSID
)
- 浏览器会将cookie随每个请求一起发送到服务器
- 服务器(PHP)使用包含会话id的cookie来知道哪个文件对应于该用户
会话文件中的数据是会话的内容,
序列化(即,表示为字符串--使用函数,如
) ; 并在加载文件时取消序列化
PHP,以填充$\u会话
数组
有时,会话id不存储在cookie中,而是发送进来
URL也是——但这很少见,n