react 验证身份证
In this tutorial we’ll be building a simple react application with authorization using Firebase with private routes. Before we dig in to the details, i would like to mention about some ready to use react website templates and web application templates, which comes with Firebase Authentication. You can check them out and use directly in your project to save lots of time and money, also they are built by experienced developers, so you get chance to learn a lots as well.
在本教程中,我们将使用带有私有路由的Firebase构建具有授权的简单React应用程序。 在深入研究细节之前,我想提一下Firebase身份验证随附的一些随时可以使用的React网站模板和Web应用程序模板。 您可以签出它们并直接在您的项目中使用,以节省大量时间和金钱,而且它们是由经验丰富的开发人员构建的,因此您也有机会学习很多东西。
Let’s now move to our tutorial.
现在转到教程。
We use authentication to recognizing a user’s identity. At the end of this article, we’ll have built a simple React that allows users to authenticate using Firebase and we’ll make sure that only authenticated users can access the application.
我们使用身份验证来识别用户的身份。 在本文的结尾,我们将构建一个简单的React,它允许用户使用Firebase进行身份验证,并确保只有经过身份验证的用户才能访问该应用程序。
To create a project in React run the command bellow:
要在React中创建项目,请运行以下命令:
npx create-react-app react_firebase_authnpx is a package runner tool that comes with npm 5.2+. We just created a project named react_firebase_auth. Go to the project and start it.
NPX是一个包亚军工具自带的NPM 5.2+。 我们刚刚创建了一个名为react_firebase_auth的项目。 转到项目并启动它。
cd react_firebase_authnpm startWe will need some dependecies for our application such as:
我们将需要一些依赖于我们的应用程序,例如:
react-dom that contains the DOM bindings for React Router, I mean, the router components for websites.npm install –save react-router-dom
react-dom包含React Router的DOM绑定,我的意思是网站的路由器组件。npminstall –save react-router-dom
material-ui to implement Google’s Material Design.npm i @material-ui/core –save
material-ui来实现Google的Material Design.npm i @ material-ui / core –save
Our react application was setuped successfully. Now it’s time to setup the firebase.
我们的react应用程序已成功设置。 现在是时候设置firebase了。
Let’s begin by creating a new firebase application. To this follow the steps bellow.Go to Firebase console.
让我们开始创建一个新的firebase应用程序。 为此,请按照以下步骤操作。转到Firebase控制台。
Press Add Project 按添加项目 Enter your app name输入您的应用名称Accept the terms接受条款Press Create Project按创建项目Wait untill the app will be created等到应用程序将被创建And press Continue然后按继续Go to Authentication tap转到身份验证水龙头Click Set up sign-in methods点击设置登录方式Chosse email/password and enable it.选择电子邮件/密码并启用它。After it is done go to Project Settings and scroll down to the list of platforms. Select Web. 完成后,转到“项目设置”,然后向下滚动到平台列表。 选择网站。 Copy your app configuration 复制您的应用配置On side bar menu click Authentication, go to Sign-in method and enable email/password.
在侧栏菜单上,单击身份验证,转到登录方法并启用电子邮件/密码。
Now let’s setup firebase in our react application. Create firebase.js file in your src folder.Install firebase dependecie using the command bellow:
现在让我们在react应用程序中设置firebase。 在src文件夹中创建firebase.js文件,使用以下命令安装firebasedependecie:
npm install --save firebaseOpen firebase.js and paste the javascript script that you copied in the Firebase Console.
打开firebase.js,然后将您复制JavaScript脚本粘贴到Firebase控制台中。
As you can see, we can iniliaze our firebase app using firebase.initializeApp and exported it as app. Doing so, we have total access to our database.
如您所见,我们可以使用firebase.initializeApp初始化我们的firebase应用程序,并将其导出为app 。 这样,我们就可以完全访问我们的数据库。
Now, go to your App.js and add some routing.
现在,转到您的App.js并添加一些路由。
import React from 'react';import "./App.css";import { BrowserRouter as Router, Route } from "react-router-dom";import Home from './Home'import Login from './Login'import SignUp from './Signup'function App() { return ( <Router> <div> <Route exact path="/" component={Home} /> <Route exact path="/login" component={Login} /> <Route exact path="/signup" component={SignUp} /> </div> </Router> );}export default App;We wrapped our layout into BrowserRouter that provides browser context to all our application. Basically it allows us to use Routes, Links, Redirects and other routers features.
我们将布局包装到BrowserRouter中,该浏览器为所有应用程序提供浏览器上下文。 基本上,它使我们可以使用路由,链接,重定向和其他路由器功能。
Now, to work with authentication we will need to have to store our authentication states, if you’re logged in or not and update our component tree. To do this we’ll use React Context API.
现在,要进行身份验证,无论是否登录,我们都必须存储身份验证状态并更新组件树。 为此,我们将使用React Context API。
Create Authentication.js in your scr folder and past this:
在您的scr文件夹中创建Authentication.js ,然后进行以下操作:
import React, { useEffect, useState } from "react"; import app from "./firebase.js"; export const AuthContext = React.createContext(); export const AuthProvider = ({ children }) => { const [currentUser, setCurrentUser] = useState(null); const [pending, setPending] = useState(true); useEffect(() => { app.auth().onAuthStateChanged((user) => { setCurrentUser(user) setPending(false) }); }, []); if(pending){ return <>Please wait...</> } return ( <AuthContext.Provider value={{ currentUser }} > {children} </AuthContext.Provider> ); };In this file we had to import app from firebase.js where we have our firebase API and we created a context. Context in react is everthing that allows you to propagate some data to the whole react component tree.
在此文件中,我们必须从firebase.js导入应用程序,在此我们具有firebase API并创建了上下文。 react中的上下文是无处不在的,它允许您将一些数据传播到整个react组件树。
And we created a provider component that let’s you store our authentication state. It holders an user and we will update evertime our authentication states will change in firebase. For this we use hook, useEffect, to signup for changes to our firebase object and we pass an empty array to our useEffect as a second argument so that it will run once when component AuthProvider will be mounted in our tree.
我们创建了一个提供程序组件,可让您存储身份验证状态。 它拥有一个用户,并且我们将随时更新我们的身份验证状态在firebase中的变化。 为此,我们使用钩子useEffect来注册对Firebase对象的更改,并将空数组作为第二个参数传递给useEffect ,以便当组件AuthProvider装入树中时它将运行一次。
Then in our AuthProvider layout we used AuthProvider.Provider and we passed our current user that we get from firebase on every auth state change, we passed it as a value to our AuthProvider.Provider and then we render children passed to this component.
然后,在我们的AuthProvider布局中,我们使用AuthProvider.Provider,并传递当前用户,该用户是在每次auth状态更改时从firebase获取的,并将其作为值传递给AuthProvider.Provider ,然后呈现传递给此组件的子代。
Now, go back to App.js and wrap our layout into AuthProvider.
现在,回到App.js并将我们的布局包装到AuthProvider中。
<AuthProvider> <Router> <div> <Route exact path="/" component={Home} /> <Route exact path="/login" component={Login} /> <Route exact path="/signup" component={SignUp} /> </div> </Router> </AuthProvider>So, everthing bellow it in our component tree will have access to current user through the context API. In our case if you’re logged in you’ll have user object having all the user description and if you´re logged out you’ll have null or undefined state user object.
因此,在我们的组件树中,无论如何,它都可以通过上下文API来访问当前用户。 在我们的情况下,如果您已登录,则将拥有包含所有用户描述的用户对象;如果您已注销,则将具有null或未定义状态的用户对象。
We can create our privates routes to allow only the authenticated users can go to the home page.
我们可以创建私有路由,以仅允许经过身份验证的用户访问首页。
Create PrivateRoute.js in your scr folder.
在您的scr文件夹中创建PrivateRoute.js。
import React, { useContext } from "react";import { Route, Redirect } from "react-router-dom";import { AuthContext } from "./Authentication";const PrivateRoute = ({ component: RouteComponent, ...rest }) => { const {currentUser} = useContext(AuthContext); return ( <Route {...rest} render={routeProps => !!currentUser ? ( <RouteComponent {...routeProps} /> ) : ( <Redirect to={"/login"} /> ) } /> );};export default PrivateRouteHere we need to know what component should be render if user is authenticated. So we take component and the rest of the props { component: RouteComponent, …rest }.PrivateRouter wil be basically a wrapper on regular routes. So we pass the rest of the props {…rest} and then in our route render function, depending if we have user or not, we will render our route component or redirect to login page.
在这里,我们需要知道如果用户通过了身份验证,应该呈现什么组件。 因此,我们采用component和其余的props {component:RouteComponent,…rest}。 基本上, PrivateRouter将成为常规路由的包装。 因此,我们传递其余的道具{…rest},然后在路由渲染函数中,根据是否有用户,我们将渲染路由组件或重定向到登录页面。
Go back to your App.js and make these changes:
返回您的App.js并进行以下更改:
<AuthProvider> <Router> <div> <PrivateRoute exact path="/" component={Home} /> <Route exact path="/login" component={Login} /> <Route exact path="/signup" component={SignUp} /> </div> </Router> </AuthProvider>Now let’s create our view components. We’ll use material UI for this. To get more deeper about Material-UI you can click here to get it done, using the official documentation.
现在让我们创建视图组件。 我们将为此使用材料UI。 要更深入地了解Material-UI,您可以单击此处以使用官方文档完成它。
We’ll use materil-ui for our interfaces. Make sure you have installed the material-ui dependecie.
我们将对接口使用materil-ui。 确保您已经安装了material-ui依赖项。
NOTE: In this article we’re covering the Firebase Authentication. So, for more details about material-ui go to official documentation.
注意:在本文中,我们将介绍Firebase身份验证。 因此,有关material-ui的更多详细信息,请转到官方文档。
Let’s create SignIn.js in your src folder and past the code bellow.
让我们在src文件夹中并在下面的代码中创建SignIn.js 。
import React from 'react';import Button from '@material-ui/core/Button';import CssBaseline from '@material-ui/core/CssBaseline';import TextField from '@material-ui/core/TextField';import FormControlLabel from '@material-ui/core/FormControlLabel';import Checkbox from '@material-ui/core/Checkbox';import Grid from '@material-ui/core/Grid';import Box from '@material-ui/core/Box';import Typography from '@material-ui/core/Typography';import { makeStyles } from '@material-ui/core/styles';import Container from '@material-ui/core/Container';import { Link } from 'react-router-dom'function Copyright() { return ( <Typography variant="body2" color="textSecondary" align="center"> {'Copyright © '} <Link color="inherit" href="https://wrappixel.com/"> WrapPixel - Best Dashboard Resources </Link>{' '} {new Date().getFullYear()} {'.'} </Typography> );}const useStyles = makeStyles((theme) => ({ paper: { marginTop: theme.spacing(8), display: 'flex', flexDirection: 'column', alignItems: 'center', }, avatar: { margin: theme.spacing(1), backgroundColor: theme.palette.secondary.main, }, form: { width: '100%', // Fix IE 11 issue. marginTop: theme.spacing(1), }, submit: { margin: theme.spacing(3, 0, 2), },}));export default function SignIn() { const classes = useStyles(); return ( <Container component="main" maxWidth="xs"> <CssBaseline /> <div className={classes.paper}> <img alt="" src={require("./assets/images/WrapPixel.png")} width="50%" /> <Typography component="h1" variant="h5"> Sign in </Typography> <form className={classes.form} noValidate> <TextField variant="outlined" margin="normal" required fullWidth id="email" label="Email Address" name="email" autoComplete="email" autoFocus /> <TextField variant="outlined" margin="normal" required fullWidth name="password" label="Password" type="password" id="password" autoComplete="current-password" /> <FormControlLabel control={<Checkbox value="remember" color="primary" />} label="Remember me" /> <Button type="submit" fullWidth variant="contained" color="primary" className={classes.submit} > Sign In </Button> <Grid container> <Grid item xs> <Link href="#" variant="body2"> Forgot password? </Link> </Grid> <Grid item> <Link href="#" variant="body2"> {"Don't have an account? Sign Up"} </Link> </Grid> </Grid> </form> </div> <Box mt={8}> <Copyright /> </Box> </Container> );}Create SignUp.js in your scr folder.
在您的scr文件夹中创建SignUp.js 。
import React from 'react';import Button from '@material-ui/core/Button';import CssBaseline from '@material-ui/core/CssBaseline';import TextField from '@material-ui/core/TextField';import FormControlLabel from '@material-ui/core/FormControlLabel';import Checkbox from '@material-ui/core/Checkbox';import Grid from '@material-ui/core/Grid';import Box from '@material-ui/core/Box';import Typography from '@material-ui/core/Typography';import { makeStyles } from '@material-ui/core/styles';import Container from '@material-ui/core/Container';import { Link } from 'react-router-dom'function Copyright() { return ( <Typography variant="body2" color="textSecondary" align="center"> {'Copyright © '} <Link color="inherit" href="https://material-ui.com/"> Your Website </Link>{' '} {new Date().getFullYear()} {'.'} </Typography> );}const useStyles = makeStyles((theme) => ({ paper: { marginTop: theme.spacing(8), display: 'flex', flexDirection: 'column', alignItems: 'center', }, avatar: { margin: theme.spacing(1), backgroundColor: theme.palette.secondary.main, }, form: { width: '100%', // Fix IE 11 issue. marginTop: theme.spacing(3), }, submit: { margin: theme.spacing(3, 0, 2), },}));export default function SignUp() { const classes = useStyles(); return ( <Container component="main" maxWidth="xs"> <CssBaseline /> <div className={classes.paper}> <img alt="" src={require("./assets/images/WrapPixel.png")} width="50%" /> <Typography component="h1" variant="h5"> Sign up </Typography> <form className={classes.form} noValidate> <Grid container spacing={2}> <Grid item xs={12} sm={6}> <TextField autoComplete="fname" name="firstName" variant="outlined" required fullWidth id="firstName" label="First Name" autoFocus /> </Grid> <Grid item xs={12} sm={6}> <TextField variant="outlined" required fullWidth id="lastName" label="Last Name" name="lastName" autoComplete="lname" /> </Grid> <Grid item xs={12}> <TextField variant="outlined" required fullWidth id="email" label="Email Address" name="email" autoComplete="email" /> </Grid> <Grid item xs={12}> <TextField variant="outlined" required fullWidth name="password" label="Password" type="password" id="password" autoComplete="current-password" /> </Grid> <Grid item xs={12}> <FormControlLabel control={<Checkbox value="allowExtraEmails" color="primary" />} label="I want to receive inspiration, marketing promotions and updates via email." /> </Grid> </Grid> <Button type="submit" fullWidth variant="contained" color="primary" className={classes.submit} > Sign Up </Button> <Grid container justify="flex-end"> <Grid item> <Link to="/signin" variant="body2"> Already have an account? Sign in </Link> </Grid> </Grid> </form> </div> <Box mt={5}> <Copyright /> </Box> </Container> );}Create Home.js in your scr folder.
在scr文件夹中创建Home.js。
import React from 'react';import { makeStyles } from '@material-ui/core/styles';import AppBar from '@material-ui/core/AppBar';import Toolbar from '@material-ui/core/Toolbar';import Typography from '@material-ui/core/Typography';import Button from '@material-ui/core/Button';import IconButton from '@material-ui/core/IconButton';import MenuIcon from '@material-ui/icons/Menu';const useStyles = makeStyles((theme) => ({ root: { flexGrow: 1, }, menuButton: { marginRight: theme.spacing(2), }, title: { flexGrow: 1, },}));export default function ButtonAppBar() { const classes = useStyles(); return ( <div className={classes.root}> <AppBar position="static"> <Toolbar> <IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu"> <MenuIcon /> </IconButton> <Typography variant="h6" className={classes.title}> News </Typography> <Button color="inherit">Login</Button> </Toolbar> </AppBar> </div> );}In SignUp.js file make these changes:
在SignUp.js文件中进行以下更改:
import { Link } from 'react-router-dom'import app from "./firebase.js";And
和
export default function SignUp({ history }) { const classes = useStyles(); const handleSignUp = useCallback(async event => { event.preventDefault(); const { email, password } = event.target.elements; try { await app .auth() .createUserWithEmailAndPassword(email.value, password.value); history.push("/"); } catch (error) { alert(error); } }, [history]);.........This component is getting history object from our routing context. When we click on that button our handleSignUp will fire. Inside this function we get our event and calll preventDefault() because we want to reload the page when user clicks on signup button. Then we get out email and password inputs from target.elements and we call createUserWithEmailAndPassword() from firebase API and we pass our email and password values: createUserWithEmailAndPassword(email.value, password.value).And then we pass our handleSignUp function to onSubmit callback of our form.
该组件正在从路由上下文获取历史记录对象。 当我们单击该按钮时,将触发handleSignUp 。 在此函数内,我们获取事件和calll preventDefault(),因为我们希望在用户单击注册按钮时重新加载页面。 然后我们从target.elements中获取电子邮件和密码输入,并从firebase API中调用createUserWithEmailAndPassword() ,然后传递电子邮件和密码值: createUserWithEmailAndPassword(email.value,password.value) ,然后将handleSignUp函数传递给onSubmit我们表格的回调。
In the SignIn.js file, SignIn.js make these imports:
在SignIn.js文件中,SignIn.js进行以下导入:
import React, { useCallback, useContext } from 'react'; // add {useCallback, useContext}import { withRouter, Redirect } from "react-router";import app from "./firebase.js";import { AuthContext } from "./Authentication.js";In the SignIn() function make these changes:
在SignIn()函数中进行以下更改:
Add history 添加历史 Add handleLogin method. export default function SignIn({history}) { const classes = useStyles(); const handleLogin = useCallback( async event => { event.preventDefault(); const { email, password } = event.target.elements; try { await app .auth() .signInWithEmailAndPassword(email.value, password.value); history.push(“/”); } catch (error) { alert(error); } }, [history] ); const { currentUser } = useContext(AuthContext); if (currentUser) { return ; } … … … … 添加handleLogin方法。 导出默认函数SignIn({history}){const classes = useStyles(); const handleLogin = useCallback(异步事件=> {event.preventDefault(); const {电子邮件,密码} = event.target.elements;尝试{等待应用程序.auth().signInWithEmailAndPassword(email.value,password.value);历史.push(“ /”);} catch(错误){alert(error);}},[历史]); const {currentUser} = useContext(AuthContext); 如果(currentUser){返回; }………………There are two differences with SignUp page. Here we use signInWithEmailAndPassword() and we use our authentication contextconst { currentUser } = useContext(AuthContext); . As you migth have remember we are tracking firebase user and we update our context with currentUser field using our auth model. And then we check: if we have currentUser we render Redirect component from react router. This component when rendered will just redirect to path that use set in the to attribute.
“注册”页面有两个区别。 在这里,我们使用signInWithEmailAndPassword(),并使用身份验证上下文const { currentUser } = useContext(AuthContext); 。 如您所知,我们正在跟踪Firebase用户,并使用auth模型使用currentUser字段更新上下文。 然后我们检查:如果有currentUser,我们将从react路由器渲染Redirect组件。 呈现时,此组件将仅重定向到使用to属性中的set的路径。
Basically, in Home.js we call signOut() from auth module in our logout button.
基本上,在Home.js中,我们从注销按钮的auth模块中调用signOut () 。
onClick={() => app.auth().signOut()}Congratulations!!! Test your app.
恭喜!!! 测试您的应用。
npm startOur application is ready. Now you’re able to use Firebase Authentication in your React application.
我们的申请已经准备就绪。 现在,您可以在React应用程序中使用Firebase身份验证。
Thanks for reading!
谢谢阅读!
翻译自: https://medium.com/javascript-in-plain-english/setting-up-firebase-authentication-in-react-application-c49f1df8b8ab
react 验证身份证
相关资源:费用经理React:一个使用React:atom_symbol:,Firebase进行存储和身份验证的:money_bag:费用跟踪应用程序-源码