如何在前端實(shí)現(xiàn)自動(dòng)或無(wú)感化的登錄態(tài)管理储矩,包括用戶注冊(cè)、登錄即硼、接口校驗(yàn)登錄態(tài)以及實(shí)現(xiàn)自動(dòng)化請(qǐng)求時(shí)自動(dòng)攜帶訪問(wèn)令牌屡拨。我們將探討兩種常見(jiàn)的實(shí)現(xiàn)方式:使用 HTTP Cookie 和前端存儲(chǔ)和發(fā)送訪問(wèn)令牌。
1. 注冊(cè)和登錄
首先裂允,用戶需要通過(guò)注冊(cè)和登錄來(lái)獲取訪問(wèn)令牌。
1.1 注冊(cè)接口
在注冊(cè)接口中僻澎,用戶提供必要的注冊(cè)信息(如用戶名和密碼)十饥,服務(wù)器對(duì)用戶進(jìn)行驗(yàn)證并創(chuàng)建用戶賬戶逗堵。
示例代碼(Node.js + Express):
// 注冊(cè)接口
app.post('/register', async (req, res) => {
try {
const { username, email, password } = req.body;
// 檢查用戶名和郵箱是否已被注冊(cè)
if (users.some(user => user.username === username)) {
return res.status(400).json({ error: '用戶名已被注冊(cè)' });
}
if (users.some(user => user.email === email)) {
return res.status(400).json({ error: '郵箱已被注冊(cè)' });
}
// 使用bcrypt對(duì)密碼進(jìn)行哈希處理
const hashedPassword = await bcrypt.hash(password, 10);
// 創(chuàng)建新用戶對(duì)象
const user = {
id: Date.now().toString(),
username,
email,
password: hashedPassword
};
// 將用戶信息存儲(chǔ)到數(shù)據(jù)庫(kù)
users.push(user);
// 創(chuàng)建訪問(wèn)令牌
const token = jwt.sign({ userId: user.id }, 'secretKey');
res.status(201).json({ message: '注冊(cè)成功', token });
} catch (error) {
res.status(500).json({ error: '注冊(cè)失敗' });
}
});
1.2 登錄接口
在登錄接口中蜒秤,用戶提供登錄憑據(jù)(如用戶名和密碼),服務(wù)器驗(yàn)證憑據(jù)的正確性并頒發(fā)訪問(wèn)令牌攘滩。
示例代碼(Node.js + Express):
app.post('/login', (req, res) => {
// 獲取登錄憑據(jù)
const { username, password } = req.body;
// 在此處進(jìn)行用戶名和密碼的驗(yàn)證轰驳,如檢查用戶名是否存在弟灼、密碼是否匹配等
// 驗(yàn)證成功,頒發(fā)訪問(wèn)令牌
const token = createAccessToken(username);
// 將訪問(wèn)令牌寫(xiě)入 Cookie
res.cookie('token', token, {
httpOnly: true,
secure: true, // 僅在 HTTPS 連接時(shí)發(fā)送 Cookie
sameSite: 'Strict' // 限制跨站點(diǎn)訪問(wèn)勤哗,提高安全性
});
// 返回登錄成功的響應(yīng)
res.status(200).json({ message: '登錄成功' });
});
2. 接口校驗(yàn)登錄態(tài)
在需要校驗(yàn)登錄態(tài)的受保護(hù)接口中芒划,服務(wù)器將校驗(yàn)請(qǐng)求中的登錄憑據(jù)(Cookie 或訪問(wèn)令牌)的有效性欧穴。
示例代碼(Node.js + Express):
app.get('/protected', (req, res) => {
// 從請(qǐng)求的 Cookie 中提取訪問(wèn)令牌
const token = req.cookies.token;
// 或從請(qǐng)求頭部中提取訪問(wèn)令牌,如果采用前端存儲(chǔ)和發(fā)送訪問(wèn)令牌方式
// const token = req.headers.authorization.split(' ')[1]; // 示例代碼拼苍,需根據(jù)實(shí)際情況進(jìn)行解析
// 檢查訪問(wèn)令牌的有效性
if (!token) {
return res.status(401).json({ error: '未提供訪問(wèn)令牌' });
}
try {
// 驗(yàn)證訪問(wèn)令牌
const decoded = verifyAccessToken(token);
// 在此處進(jìn)行更詳細(xì)的用戶權(quán)限校驗(yàn)等操作
// 返回受保護(hù)資源
res.status(200).json({ message: '訪問(wèn)受保護(hù)資源成功' });
} catch (error) {
res.status(401).json({ error: '無(wú)效的訪問(wèn)令牌' });
}
});
3. 自動(dòng)化登錄態(tài)管理
要實(shí)現(xiàn)自動(dòng)或無(wú)感化的登錄態(tài)管理疮鲫,前端需要在每個(gè)請(qǐng)求中自動(dòng)攜帶訪問(wèn)令牌(Cookie 或請(qǐng)求頭部)。
3.1 使用 HTTP Cookie
當(dāng)使用 HTTP Cookie 時(shí)俊犯,瀏覽器會(huì)自動(dòng)將 Cookie 包含在每個(gè)請(qǐng)求的頭部中,無(wú)需手動(dòng)設(shè)置者祖。
示例代碼(前端使用 JavaScript):
// 發(fā)送請(qǐng)求時(shí)绢彤,瀏覽器自動(dòng)攜帶 Cookie
fetch('/protected');
`````javascript
// 發(fā)送請(qǐng)求時(shí),瀏覽器自動(dòng)攜帶 Cookie
fetch('/protected');
3.2 前端存儲(chǔ)和發(fā)送訪問(wèn)令牌
當(dāng)使用前端存儲(chǔ)和發(fā)送訪問(wèn)令牌時(shí),前端需要在每個(gè)請(qǐng)求的頭部中手動(dòng)設(shè)置訪問(wèn)令牌奇适。
示例代碼(前端使用 JavaScript):
// 從存儲(chǔ)中獲取訪問(wèn)令牌
const token = localStorage.getItem('token');
// 設(shè)置請(qǐng)求頭部
const headers = {
'Authorization': `Bearer ${token}`
};
// 發(fā)送請(qǐng)求時(shí)芦鳍,手動(dòng)設(shè)置請(qǐng)求頭部
fetch('/protected', { headers });
在上述示例代碼中,我們使用了前端的 localStorage
來(lái)存儲(chǔ)訪問(wèn)令牌皮仁,并在發(fā)送請(qǐng)求時(shí)手動(dòng)設(shè)置了請(qǐng)求頭部的 Authorization
字段菲宴。
請(qǐng)注意,無(wú)論使用哪種方式势誊,都需要在服務(wù)器端進(jìn)行訪問(wèn)令牌的驗(yàn)證和安全性檢查粟耻,以確保請(qǐng)求的合法性和保護(hù)用戶數(shù)據(jù)的安全眉踱。
補(bǔ)充說(shuō)明:
-
createUser
:自定義函數(shù),用于創(chuàng)建用戶賬戶并將其保存到數(shù)據(jù)庫(kù)或其他持久化存儲(chǔ)中册烈。 -
createAccessToken
:自定義函數(shù)婿禽,用于創(chuàng)建訪問(wèn)令牌矮冬。 -
verifyAccessToken
:自定義函數(shù)胎署,用于驗(yàn)證訪問(wèn)令牌的有效性窑滞。
寫(xiě)在最后
文章旨在答疑掃盲,內(nèi)容簡(jiǎn)明扼要方便學(xué)習(xí)了解巨坊,請(qǐng)確保在實(shí)際應(yīng)用中采取適當(dāng)?shù)陌踩胧﹣?lái)保護(hù)用戶的登錄憑據(jù)和敏感數(shù)據(jù)趾撵,保持學(xué)習(xí)共啃,共勉~