使用session實現登錄的思路:
1.服務端收到客戶端請求,解析請求頭獲取sessionId。
2.如果sessionId不存在,則生成一個唯一的sessionId,生成sessionId的規則可以根據自己需要設置,這裏使用時間戳+隨機數生成sessionId。並且設置cookie。
3.根據sessionId從SESSION_DATA這個全局變量中讀取session數據,如果不存在,初始化爲空對象{},如果存在,說明用戶已登錄過
4.用戶訪問localhost:8002/login?username=test&password=123登錄成功,存儲session數據到SESSION_DATA中。
5.可以通過訪問localhost:8002/getUserInfo獲取session中的登錄信息
const http = require('http')
const querystring = require('querystring')
const getCookieExpires = () => {
const d = new Date()
d.setTime(d.getTime() + (24 * 60 * 60 * 1000))
return d.toGMTString()
}
// 直接這麼設置session數據,session會存在nodejs進程中,會存在以下問題:
// 1.進程內存有限,如果訪問量過大,session過大,導致內存暴增。
// 2.線上環境,是多進程的,進程之間無法共享內存
const SESSION_DATA = {}
const server = http.createServer(async (req, res) => {
// 設置返回格式爲JSON
// 在原生的node開發中,res.end返回的永遠都是字符串,但是可以通過res.setHeader('Content-type', 'application/json')
// 設置返回的數據格式,客戶端拿到返回結果會根據返回的數據格式解析數據
res.setHeader('Content-type', 'application/json')
const url = req.url
req.path = url.split('?')[0]
req.query = querystring.parse(url.split('?')[1])
req.cookie = {}
const cookie = req.headers.cookie || ''
cookie && cookie.split(';').forEach(item => {
const arr = item.split('=')
const key = arr[0].trim()
req.cookie[key] = arr[1].trim()
})
//解析session
let sessionId = req.cookie.sessionId
if(!sessionId){
sessionId = `${Date.now()}_${Math.random()}`
// httpOnly:只允許後端修改,不允許前端修改
res.setHeader('Set-Cookie', `sessionId=${sessionId};path=/;httpOnly;expires=${getCookieExpires()}`)
}
req.session = SESSION_DATA[sessionId] = SESSION_DATA[sessionId] || {}
if(req.method === 'GET' && req.path === '/login'){
const { username, password } = req.query
if(username === 'test' && password === '123'){
req.session.username = 'test'
req.session.password = '123'
res.end('login success')
} else {
res.end('login fail')
}
return
}
if(req.method === 'GET' && req.path === '/getUserInfo'){
if(req.session.username){
res.end(JSON.stringify({ username: req.session.username, password: req.session.password }))
} else {
res.end('not login')
}
return
}
res.writeHead(404, { "Content-type": "text/plain" })
res.write("404 Not Found\n")
res.end()
})
server.listen(8002)
6.總結,使用node.js本地變量存儲session,有很大的問題,服務重啓,這些信息都會丟失,而且進程之間無法共享用戶信息,因此可以考慮將session數據存儲到redis中