所以这是我的问题:
我在我的项目中使用 Next.js,我通过 OAuth 服务对用户进行身份验证。因此用户的流程如下:
用户点击“登录按钮”->
用户被重定向到 OAuth 提供商以确认 ->
正在使用 url 查询参数 https://kupbsv.vercel.app/?code=1a6a0490bbgCdef75b399e30d&state=2d601e4c-9660-40ff-a1c8-de241844b1c0
-> 将用户重定向回我的应用程序
我的应用程序使用此参数获取 Access Tokens
并将其保存在本地存储中 ->
然后我使用这个令牌从提供者获取用户数据并将其显示在 profile
组件
该过程正常工作,但在重定向回我的应用程序后,我仍然看到 LogIn button
,就像没有用户一样,但身份验证已完成,我在本地存储中有 Access Token
。页面重新加载后一切正常,所以问题是在获取数据之前呈现页面。现在,在使用查询参数重定向以摆脱它们之后,我通过使用 router.push('/home')
的解决方法解决了它。如果没有 router.push()
在页面呈现前获取数据,我能做些什么来解决这个问题。
这是我的代码:
Header.js
export default function Header(props) {
const { query } = useRouter();
const router = useRouter();
const [userName, setUserName] = useRecoilState(recoilUserName)
const [userPrimaryPaymail, setUserPrimaryPaymail] = useRecoilState(recoilUserPrimaryPaymail)
const [userEmail, setUserEmail] = useRecoilState(recoilUserEmail)
const [userAvatarUrl, setUserAvatarUrl] = useRecoilState(recoilUserAvatarUrl)
const [userStatus, setUserStatus] = useRecoilState(recoilUserStatus)
const [userAmount, setUserAmount] = useRecoilState(recoilUserAmount)
const [userCurrency, setUserCurrency] = useRecoilState(recoilUserCurrency)
const [userId, setUserId] = useRecoilState(recoilUserId)
const [refreshToggle, setRefreshToggle] = useState(true)
const userProfile = async() => {
if (query.code && !userId) {
await handleAuthuser();
const { profile, balance, userStatus } = await getUserData();
setUserName(profile.name);
setUserPrimaryPaymail(profile.primaryPaymail);
setUserEmail(profile.email);
setUserAvatarUrl(profile.avatarUrl);
setUserStatus(userStatus.data.status);
setUserAmount(balance.amount);
setUserCurrency(balance.currency);
setUserId(profile.id);
}
if (storage.getItem('mb_js_client:oauth_access_token') && !userId) {
const { profile, balance, userStatus } = await getUserData();
setUserName(profile.name);
setUserPrimaryPaymail(profile.primaryPaymail);
setUserEmail(profile.email);
setUserAvatarUrl(profile.avatarUrl);
setUserStatus(userStatus.data.status);
setUserAmount(balance.amount);
setUserCurrency(balance.currency);
setUserId(profile.id);
}
}
userProfile();
return (
<div className="main">
<header className="header">
<Link as="/" href="/" ><a className="logo">KUPBSV</a></Link>
<a className="push" >
{!userId ? <LoginDialog /> :
<Profile name={userName} userId={userId} primaryPaymail={userPrimaryPaymail} userEmail={userEmail} userAvatar={userAvatarUrl} userAmount={userAmount} userCurrency={userCurrency} userStatus={userStatus}/> }
</a>
<a><SimpleMenu userId={userId} /></a>
</header>
getUserData.js
const { MoneyButtonClient } = require('@moneybutton/api-client')
export default async function getUserData () {
const client = new MoneyButtonClient('xxxxxxxxxxxxxxx');
const { id } = await client.getIdentity()
const status = await fetch( 'https://kyc.blockpass.org/kyc/1.0/connect/xxxxxx/refId/'+id, {
headers: {
'Authorization': 'xxxxxxxxxxxx'
},
});
const userStatus = await status.json()
const profile = await client.getUserProfile(id)
const balance = await client.getBalance(id)
console.log(userStatus);
return {
profile: profile,
balance: balance,
userStatus: userStatus
}
handleAuth.js
const { MoneyButtonClient } = require('@moneybutton/api-client')
export default async function handleAuthuser () {
const client = new MoneyButtonClient('xxxxxxxx');
client.handleAuthorizationResponse();
router.push('/home')
}
所以在使用 LoginDialog
后,用户被重定向到 MoneyButton OAuth 服务,然后他被重定向回我的应用程序,并在 url 中使用查询参数。 handleAuth
函数接受查询参数并获取访问令牌以将其保存在本地存储中。 getUserData
正在使用令牌获取用户数据。