Reactjs 使用AWS的受保护路由使用React上下文进行放大
我正在将一个应用程序从Firebase迁移到AWS Amplify。我想创建一个React上下文,如果用户未登录,它将提供路由保护 例如,我的Auth.js文件:Reactjs 使用AWS的受保护路由使用React上下文进行放大,reactjs,amazon-web-services,aws-amplify,react-context,Reactjs,Amazon Web Services,Aws Amplify,React Context,我正在将一个应用程序从Firebase迁移到AWS Amplify。我想创建一个React上下文,如果用户未登录,它将提供路由保护 例如,我的Auth.js文件: import React, { useEffect, useState, createContext } from 'react' import fire from './firebase' export const AuthContext = createContext() export const AuthProvider =
import React, { useEffect, useState, createContext } from 'react'
import fire from './firebase'
export const AuthContext = createContext()
export const AuthProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState(null)
useEffect(() => {
fire.auth().onAuthStateChanged(setCurrentUser)
}, [])
return (
<AuthContext.Provider value={{ currentUser }}>
{children}
</AuthContext.Provider>
)
}
import React,{useffect,useState,createContext}来自“React”
从“/firebase”导入火
export const AuthContext=createContext()
导出常量AuthProvider=({children})=>{
常量[currentUser,setCurrentUser]=useState(null)
useffect(()=>{
fire.auth().onAuthStateChanged(setCurrentUser)
}, [])
返回(
{儿童}
)
}
和我的App.js文件:
import * as React from 'react'
import { BrowserRouter, Switch, Route } from 'react-router-dom'
import Navbar from './components/navbar/navbar'
import Home from './routes/Home'
import Register from './routes/Register'
import Footer from './components/footer/Footer'
import AlertProvider from './components/notification/NotificationProvider'
import MyAlert from './components/notification/Notification'
import { AuthProvider } from './Auth'
import PrivateRoute from './PrivateRoute'
const App = () => {
return (
<AuthProvider>
<BrowserRouter>
<AlertProvider>
<div className="app">
<Navbar />
<MyAlert />
<Switch>
<Route path="/" exact component={Home} />
<Route
path="/register"
exact
component={Register}
/>
<Route
path="/forgot-password"
render={(props) => <div>Forgot Password</div>}
/>
<Route path="*" exact={true} component={Home} />
</Switch>
<Footer />
</div>
</AlertProvider>
</BrowserRouter>
</AuthProvider>
)
}
export default App
import*作为来自“React”的React
从“react router dom”导入{BrowserRouter,Switch,Route}
从“./components/Navbar/Navbar”导入导航栏
从“./routes/Home”导入主页
从“./routes/Register”导入寄存器
从“./components/Footer/Footer”导入页脚
从“./components/notification/NotificationProvider”导入AlertProvider
从“./components/notification/notification”导入MyAlert
从“/Auth”导入{AuthProvider}
从“/PrivateRoute”导入PrivateRoute
常量应用=()=>{
返回(
忘记密码}
/>
)
}
导出默认应用程序
这一切都很好
我如何使用AWS Amplify做类似的事情?基本上,我将如何创建一个Auth.js文件,该文件将环绕我的路由,并为它们提供一个用户上下文(当用户的身份验证状态更改时,该上下文将更新)
谢谢 您可以通过设置自定义的
protectedRoute
HOC来实现这一点,该HOC将用于保护任何需要身份验证的路由。它将检查用户是否已登录,如果用户未登录,则会将其重新定向到指定的路由
protectedRoute.js
import React, { useEffect } from 'react'
import { Auth } from 'aws-amplify'
const protectedRoute = (Comp, route = '/profile') => (props) => {
async function checkAuthState() {
try {
await Auth.currentAuthenticatedUser()
} catch (err) {
props.history.push(route)
}
}
useEffect(() => {
checkAuthState()
})
return <Comp {...props} />
}
export default protectedRoute
您还可以使用来自aws amplify的预先构建的名为的HOC with Authenticator
,它提供用户界面并检查用户身份验证状态
配置文件页面的示例用例:
import React, { useState, useEffect } from 'react'
import { Button } from 'antd'
import { Auth } from 'aws-amplify'
import { withAuthenticator } from 'aws-amplify-react'
import Container from './Container'
function Profile() {
useEffect(() => {
checkUser()
}, [])
const [user, setUser] = useState({})
async function checkUser() {
try {
const data = await Auth.currentUserPoolUser()
const userInfo = { username: data.username, ...data.attributes, }
setUser(userInfo)
} catch (err) { console.log('error: ', err) }
}
function signOut() {
Auth.signOut()
.catch(err => console.log('error signing out: ', err))
}
return (
<Container>
<h1>Profile</h1>
<h2>Username: {user.username}</h2>
<h3>Email: {user.email}</h3>
<h4>Phone: {user.phone_number}</h4>
<Button onClick={signOut}>Sign Out</Button>
</Container>
);
}
export default withAuthenticator(Profile)
import React,{useState,useffect}来自“React”
从“antd”导入{Button}
从“aws放大”导入{Auth}
从“aws放大反应”导入{withAuthenticator}
从“./Container”导入容器
函数配置文件(){
useffect(()=>{
checkUser()
}, [])
const[user,setUser]=useState({})
异步函数checkUser(){
试一试{
const data=await Auth.currentUserPoolUser()
const userInfo={username:data.username,…data.attributes,}
setUser(userInfo)
}catch(err){console.log('error:',err)}
}
函数签出(){
Auth.signOut()
.catch(err=>console.log('error signing out:',err'))
}
返回(
轮廓
用户名:{user.Username}
电子邮件:{user.Email}
电话:{user.Phone_number}
退出
);
}
使用验证器导出默认值(配置文件)
两者的路径相同,下面我链接了一个我用于两者的示例:
import React, { useState, useEffect } from 'react'
import { HashRouter, Switch, Route } from 'react-router-dom'
import Nav from './Nav'
import Public from './Public'
import Profile from './Profile'
import Protected from './Protected'
const Router = () => {
const [current, setCurrent] = useState('home')
useEffect(() => {
setRoute()
window.addEventListener('hashchange', setRoute)
return () => window.removeEventListener('hashchange', setRoute)
}, [])
function setRoute() {
const location = window.location.href.split('/')
const pathname = location[location.length-1]
setCurrent(pathname ? pathname : 'home')
}
return (
<HashRouter>
<Nav current={current} />
<Switch>
<Route exact path="/" component={Public}/>
<Route exact path="/protected" component={Protected} />
<Route exact path="/profile" component={Profile}/>
<Route component={Public}/>
</Switch>
</HashRouter>
)
}
export default Router
import React,{useState,useffect}来自“React”
从“react router dom”导入{HashRouter,Switch,Route}
从“./Nav”导入导航
从“./Public”导入公共
从“./Profile”导入配置文件
从“./Protected”导入受保护的
常数路由器=()=>{
const[current,setCurrent]=useState('home')
useffect(()=>{
setRoute()
window.addEventListener('hashchange',setRoute)
return()=>window.removeEventListener('hashchange',setRoute)
}, [])
函数setRoute(){
const location=window.location.href.split(“/”)
常量路径名=位置[location.length-1]
setCurrent(路径名?路径名:'home')
}
返回(
)
}
导出默认路由器
也许不需要使用上下文,相反,您可以使用一个HOC组件来包装受保护的路由,并检查用户是否从那里经过身份验证,然后允许他们使用路由,或者如果不允许他们重定向到指定的路径。谢谢,您是否有到代码示例的链接?我是新来的,一定会很感激一些我能消化的代码。谢谢!这是一个很好的回应,让梅格拉德更清楚它帮助了你@yudhiesh,我不理解的是你的checkAuthState函数。只有在身份验证失败时,您才会发送到配置文件。当它经过的时候,你不应该送它去某条路线吗?
import React, { useState, useEffect } from 'react'
import { HashRouter, Switch, Route } from 'react-router-dom'
import Nav from './Nav'
import Public from './Public'
import Profile from './Profile'
import Protected from './Protected'
const Router = () => {
const [current, setCurrent] = useState('home')
useEffect(() => {
setRoute()
window.addEventListener('hashchange', setRoute)
return () => window.removeEventListener('hashchange', setRoute)
}, [])
function setRoute() {
const location = window.location.href.split('/')
const pathname = location[location.length-1]
setCurrent(pathname ? pathname : 'home')
}
return (
<HashRouter>
<Nav current={current} />
<Switch>
<Route exact path="/" component={Public}/>
<Route exact path="/protected" component={Protected} />
<Route exact path="/profile" component={Profile}/>
<Route component={Public}/>
</Switch>
</HashRouter>
)
}
export default Router