在今天的文章中,我將向您展示如何在用戶通過身份驗證後在您的 React 應用程序中設置自動重定向到安全/受限頁面。
介紹
假設在您的應用程序中,您有一個頁面需要先進行身份驗證,然後用戶才能訪問它,例如儀錶板。這意味著在允許用戶訪問儀錶板之前,他必須先登錄。
現在,如果出於某種原因(會話超時、cookie 過期等),用戶退出應用程序,但需要重新訪問儀錶板上的同一頁面怎麼辦?或者他可能會嘗試通過單擊發送給他的電子郵件中的鏈接來訪問儀錶板上的信息?您如何將此用戶重定向回他在身份驗證後嘗試訪問的鏈接?
這個問題會讓你立刻明白,要求用戶先登錄才能訪問受限頁面是不夠的。但是您還應該在用戶通過身份驗證後立即將其重定向到受限頁面。
仍然感到困惑?讓我解釋得更好
所以我有這個頁面 http://my-website.com/dashboard/update-profile
需要用戶在被允許訪問之前進行身份驗證。每當未通過身份驗證的用戶嘗試訪問它時,他將被重定向到 http://my-website.com/login
現在的目標是保留此 URL http://my-website.com/dashboard/update-profile
,以便當用戶通過身份驗證成功時,他將被重定向回該 URL。
我將向您展示如何在您的 React 應用程序中實現這一點,如果您理解其中的邏輯,您可以在任何地方實現它!
使用查詢參數
在這種方法中,我將檢查用戶是否未登錄,然後檢索他試圖訪問的 URL,將其存儲在查詢參數 next
中,然後將他重定向到登錄頁面。如果身份驗證成功,我會將他重定向回 next
查詢參數中的 URL。
將此代碼放在安全/受限頁面(需要身份驗證的頁面)
為此,我需要做的第一件事是檢查用戶是否未登錄。
useEffect(() => { isAuthenticated().then(res => { //check if user is not logged in if(!res){ //---- } }}, []) //make the function run only once when the component mounts
現在我們需要創建一個新的 URL 對象,其中包含該用戶將被重定向到的鏈接,以便進行身份驗證。
在我的例子中,它將是 /login
頁面,我用它創建一個新的 URL 對象的原因是我將在稍後通過添加查詢參數來操縱鏈接。
useEffect(() => { isAuthenticated().then(res => { //check if user is not logged in if(!res){ //create a URL object with the Login Link const loginUrl = new URL('http://my-website.com/login'); } }}, []) //make the function run only once when the component mounts
在我們繼續之前,我們需要確保用戶正在嘗試訪問儀錶板中的受限頁面。我們可以通過檢查當前 URL 是否包含 /dashboard
.
我將在方法內使用正則表達式 match
對當前 URL 執行此搜索。
useEffect(() => { isAuthenticated().then(res => { //check if user is not logged in if(!res){ //create a URL object with the Login Link const loginUrl = new URL('http://my-website.com/login'); //check if user is trying to access dashboard without logging in if(window.location.href.match(new RegExp('/dashboard', 'i'))){ //--- } } }}, []) //make the function run only once when the component mounts
現在我們需要將用戶嘗試訪問的鏈接作為查詢參數附加到我們之前創建的 URL 對象,然後將用戶從該 URL 對象重定向到 完整的 URL 。
useEffect(() => { isAuthenticated().then(res => { //check if user is not logged in if(!res){ //create a URL object with the Login Link const loginUrl = new URL('http://my-website.com/login'); //check if user is trying to access dashboard without logging in if(window.location.href.match(new RegExp('/dashboard', 'i'))){ //Get the url he wanted to visit const next = window.location.href //append it to the URL object loginUrl.searchParams.append('next', next); } //redirect the user to the full URL from the URL Object window.location.href = loginUrl.href.toString() } }}, []) //make the function run only once when the component mounts
這是我們到目前為止所做的。
例如,當未通過身份驗證的用戶嘗試訪問儀錶板中的任何頁面時 http://my-website.com/dashboard/update-profile
,他將被重定向到 http://my-website.com/login?next=http://my-website.com/dashboard/update-profile
。
現在,這裡有一些事情要記住。
瀏覽器將嘗試對 next
查詢參數中的值進行編碼,因為它是一個 URL,在我們訪問該值之前,我們需要對其進行解碼。
在我這邊,這是我的地址欄的樣子
如果用戶通過身份驗證,我們就該處理重定向了。
處理重定向
現在在您的 登錄頁面上,我們將創建一個變數,該變數將存儲默認鏈接,如果身份驗證成功,用戶將被重定向到。
我們還將導入 useLocation
from react-router-dom
以便我們能夠讀取當前 URL 並檢查它是否包含搜索(查詢)參數。
import {useLocation} from 'react-router-dom';export default function Login(){ //invoke the function const location = useLocation(); //default page to redirect user after login let redirect = 'http://my-website.com/dashboard/home'; //check if there's search param in the URL if(location.search){ //--- }}
如果您不想使用該 useLocation
模塊讀取當前 URL,您同樣可以直接使用 JavaScript 訪問當前 URL。
export default function Login(){ //default page to redirect user after login let redirect = 'http://my-website.com/dashboard/home'; //create a URL object using the current url const url = new URL(window.location.href) //check if url contains a search parameter if(url.search){ //--- }}
無論您選擇使用哪種方法,接下來要做的就是讀取搜索參數並檢查它是否包含 next
.
如果它包含 next
,我們將解碼該值並將 redirect
變數的值重新分配給該 URL。
您還可以執行搜索以檢查解碼值是否包含 /dashboard
.
export default function Login(){ //default page to redirect user after login let redirect = 'http://my-website.com/dashboard/home'; //create a URL object using the current url const url = new URL(window.location.href) //check if url contains a search parameter if(url.search){ //read the search parameters const search = new URLSearchParams(url.search) //check if next parameter is present if(search?.get('next')){ //decode it const next = decodeURIComponent(search.get('next')) //check if dashboard is present in the URL if(next.match(new RegExp('/dashboard', 'i'))){ redirect = next; } } } //after authentication, redirect users to the redirect variable //window.location.href = redirect;}
因此,在身份驗證之後,您應該將用戶重定向到 redirect
變數的值,即解碼後的 URL!
在下面觀看我的實現
小提示
如果你想讓你的重定向更清晰,你可以將 URL 存儲在瀏覽器中 sessionStorage
,當你驗證它時,你可以繼續並從會話存儲中刪除它,然後將用戶重定向到該 URL。
感謝您閱讀。
噓!我願意參加網路開發和技術寫作方面的演出!
額外的
我構建了一個 JavaScript 庫,它能夠使用正則表達式、驗證規則和表單輸入屬性來驗證您的前端表單。