在今天的文章中,我将向您展示如何创建设置自动重定向以确保安全/受限React 应用程序中的页面。
简介
假设在您的应用程序中,您有一个页面需要先进行身份验证,然后用户才能访问它,例如仪表板。 这意味着在允许用户访问仪表板之前,他必须先登录。
p>现在,如果由于某种原因(会话超时、cookie 过期等)并且用户注销应用程序,但需要重新访问仪表板上的同一页面? 或者他可能试图通过单击发送给他的电子邮件中的链接来访问仪表板上的信息? 您如何将此用户重定向回他在验证后尝试访问的链接?
这个问题会让你马上明白,问用户在访问受限页面之前先登录是不够的。 但是您还应该在用户通过身份验证后立即将他们重定向到受限页面。
还在困惑吗? 让我解释得更好
所以我有这个页面http://my-website.com/dashboard/update-profile
< span style="vertical-align: inherit;"> 要求用户在被允许访问之前进行身份验证。 每当未经身份验证的用户试图访问它时,他将被重定向到 http://my-website。 com/login
现在的目标是保留This URL span>http://my-website.com/dashboard/update-profile
以便当用户成功通过身份验证时,他将被重定向回该 URL。
我会告诉你如何对齐你的React app,只要你懂逻辑,哪里都能搞定!
使用查询参数 span>
在这个方法中我会检查用户是否没有登录然后检索他试图访问的 URL,将其存储在查询参数 next
并将他重定向到登录页面。 如果身份验证成功,我将他重定向回 next
查询参数中的 URL。
将这段代码放在一个安全的地方/受限页面(需要认证的页面)
为此,我需要做的第一件事是检查用户是否未登录。
useEffect(() => { isAuthenticated ().then(res => { //检查用户是否未登录 if(!res){ //---- } }}, []) //让函数只在组件挂载时运行一次< /code>
现在我们需要创建一个包含链接的新 URL 对象此用户将被重定向以进行身份验证。
在我的示例中,它将是 /login
页面,我用它来创建一个新的 URL 对象,因为我将然后通过添加查询参数来操作链接。
useEffect(( ) => { isAuthenticated().then(res => { //检查用户是否未登录 if(!res){ //使用登录链接创建一个 URL 对象 const loginUrl = new URL('http:// my-website.com/login'); } }}, []) //让函数只在组件挂载时运行一次
在我们继续之前,我们需要确保用户正在尝试访问仪表板中的受限页面。 我们可以检查当前URL是否包含/dashboard
.
我将在方法中使用正则表达式匹配
在当前 URL 上执行此搜索。
useEffect(() => { isAuthenticated().then(res => { //检查用户是否未登录 if(!res){ //使用登录链接创建一个 URL 对象 const loginUrl = new URL('http://my-website.com/login'); //检查用户是否试图在不登录的情况下访问仪表板 if(window.location. href.match(new RegExp('/dashboard', 'i'))){ //--- } } }}, []) //让函数只在组件挂载时运行一次
p>
现在我们需要将用户尝试访问的链接作为查询参数附加到我们之前创建的 URL 对象,然后将用户从该 URL 对象重定向到 完整的 .
useEffect(() => { isAuthenticated().then(res => { //检查用户是否登录d i n if(!res){ //使用登录链接创建一个 URL 对象 const loginUrl = new URL('http://my-website.com/login'); //检查用户是否试图在不登录的情况下访问仪表板 if(window.location.href.match(new RegExp('/dashboard', 'i'))){ //获取他想访问的 url const next = window.location.href //附加到URL对象 loginUrl.searchParams.append('next', next); } // 将用户从 URL 对象重定向到完整的 URL window.location.href = loginUrl.href.toString() } }}, []) // 使函数只在组件挂载时运行一次
这就是我们到目前为止所做的。
例如,当未经身份验证的用户尝试时访问仪表板中的任何页面http://my-website.com/dashboard/update-profile
,他会被重定向到http://my-website.com/login?next=http://my- website.com/dashboard/update-profile
。
现在,这里有一些要保留的东西头脑 。
浏览器会尝试对齐 next
查询参数中的值被编码,因为它是一个 URL,在我们可以访问我们需要解码它的值之前。
在我这边,这是我的 What the地址栏看起来像
p>
如果用户通过身份验证,我们就该处理重定向了。
处理重定向
现在在你的 在登录页面,我们将创建一个变量来存储默认链接,如果身份验证成功,用户将被重定向到该链接。
我们还将导入< /span>useLocation
来自 react -router-dom
这样我们就可以读取当前 URL 并检查它是否包含搜索 (查询)参数。
import {useLocation} from 'react-router-dom';export default function Login(){ //调用函数 const location = useLocation(); //登录后重定向用户的默认页面 let redirect = 'http://my-website.com/dashboard/home'; //检查 URL 中是否有搜索参数 if(location.search){ //--- }}
如果你不想使用这个useLocation
< span style="vertical-align: inherit;"> 模块读取当前URL,也可以直接使用JavaScript访问当前URL地址。
export default function Login(){ //登录后重定向用户的默认页面 let redirect = 'http://my-website.com/dashboard/家'; //使用当前 url 创建一个 URL 对象 const url = new URL(window.location.href) //检查 url 是否包含搜索参数 if(url.search){ //--- }}
< /p>
无论你选择使用哪种方法,接下来要做的就是阅读Take the search参数并检查它是否包含 next
.< /span>
如果包含 next
,我们将解码值并替换 /span >redirect
变量的值被重新分配给 URL。
您还可以执行搜索以检查解码值是否包含/dashboard
.< /span>
export default function Login(){ //登录后重定向用户的默认页面 let redirect = 'http://my-website.com/dashboard/home '; //使用当前 url 创建一个 URL 对象 const url = new URL(window.location.href) //检查 url 是否包含搜索参数 if(url.search){ //读取搜索参数 const search = new URLSearchParams( url .search) //检查下一个参数是否存在 if(search?.get('next')){ //对其解码 const next = decodeURIComponent(search.get('next')) //检查仪表板是否存在在 URL 中 if(next.match(new RegExp('/dashboard', 'i'))){ redirect = next; } } } //身份验证后,将用户重定向到重定向变量 //window.location.href = redirect;}
所以在认证之后你应该将用户重定向到redirect
< span style="vertical-align: inherit;"> 变量的值,即解码后的URL!
在下面观看我的实现> /span>
提示 p>如果你想让你的重定向更清晰,你可以将 URL 存储在浏览器中< /span>sessionStorage
,当你验证它时,你可以继续删除它从会话存储,并将用户重定向到该 URL。
感谢您的阅读。
嘘! 我很乐意参与网络开发和技术写作方面的工作!
额外
我构建了一个 JavaScript 库,它使用正则表达式、表单、验证规则, 和表单输入属性来验证你的前端表单。