身份驗證(cookie+session & jwt驗證機制)


起因:http請求是無狀態的 , 這意味着每個請求都是獨立的, 我們給服務器發送 HTTP 請求之后,服務器根據請求,會給我們發送數據過來,但是,發送完,不會記錄任何信息。無狀態無連接,具體如何理解

 

解決方案:

 

1、cookie+session

cookie:前端;session:服務器端

 

實現過程如下:

a、前端登錄成功,后端會發布一個加密字符串(用戶相關信息)給前端,( ⚠️ 自動在前端存cookie )

b、前端調用其他接口,前端保存起來,之后每次請求的時候,將加密字符串作為參數,傳遞給服務器端(⚠️ cookie自動傳遞 )

c、服務器端拿到字符串進行解密,根據權限進行驗證,如果驗證通過的話,就可以接着執行接口邏輯

 

需要插件:

cookie-parse: 解析cookie數據

express-session: https://www.npmjs.com/package/express-session

 

const  cookieParse=require('cookie-parser')
const  session = require('express-session')

 

// seesion 整體配置
app.use(session({
    secret: 'sjfsdkjflajf', //為了安全性的考慮設置secret屬性
    cookie: {maxAge: 60 * 1000*24*7  }, //設置過期時間7天
    resave: true, // 即使 session 沒有被修改,也保存 session 值,默認為 true
    saveUninitialized: false, //無論有沒有session cookie,每次請求都設置個session cookie ,默認給個標示為 connect.sid
}));

后端存session👇

 

 

 

登錄成功,將用戶信息存到session

調用其他接口時,后端會取session,看登錄狀態是否存在

 

 前端界面如何處理👇

 

 

 

 

補充:如何注銷session:

退出登錄的接口部分👇

 

 前端部分:

 

 

 

 

易錯點⚠️:注意一定不要產生跨域(localhost&127.0.0.1)!否則cookie,session無法使用~~

以上就是原理,具體細節可能還會涉及到加密算法之類的。

 

限制性:由於域名和api不一樣的情況大有存在,session和cookie跨域限制,所以可以考慮方案二 JWT。


 

 

2、JWT安全驗證(https://jwt.io/)

 

token :header.payload.密鑰

 

 

 

jsonwebtoken  : 用npm安裝,它是實現加密解密的方法。

 

token.js

const jwt = require('jsonwebtoken')

//步驟一:產生token的私鑰
let screat = 'sflsdjfl;ajflsjflasjflasjfoas'
let payload = {  //不能放重要敏感信息
    us: 123,
    ps: 456
}
//傳遞的數據
//步驟二:通過hs256加密 ,產生一個token
// let token=jwt.sign(payload,screat) //hs256加密 數據 載荷  screat
let token = 'hbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1cyI6MTIzLCJwcyI6NDU2LCJpYXQiOjE1NTg0MjE4OTB9.8TEQ_dMFzckiMVE--7XP-jjmnl7QE68qz0bptEMn5vs'
// console.log(token)


//步驟三:驗證token的合法性

jwt.verify(token, screat, (err, data) => {//screat,密鑰
    console.log(err)
    console.log(data)
})

 

把以上代碼封裝成模塊,jwt.js 



const jwt = require('jsonwebtoken')
const scrict = 'sdjfksdjflajflasjflasjflksf'

function creatToken(palyload) {
    // 生成 jwt 邏輯
    palyload.ctime = Date.now()// ctime創建時間
    palyload.exp = 1000 * 60 * 24 * 7   //設置超時邏輯
    return jwt.sign(palyload, scrict)
}

function checkToken(token) {
    return new Promise((resovle, reject) => {
        jwt.verify(token, scrict, (err, data) => {
            if (err) {
                reject('token 驗證失敗')
            }
            resovle(data)
        })
    })

}

module.exports = {
    creatToken, checkToken
}

 

如何在 接口中 使用jwt.js👇

 

const JWT = require('../utils/jwt')//引入


router.post('/login', (req, res) => {
    let {us, ps} = req.body
    if (!us || !ps) {
        return res.send({err: -1, msg: '參數錯誤'})
    }
    // {us:us,ps:ps}  === {us,ps}

    User.find({us, ps})
        .then((data) => {
            if (data.length > 0) {
                // 登錄成功后將用戶的相關信息存到session
                //  req.session.login=true
                //  req.session.name=us
                let token = JWT.creatToken({login: true, name: us})
                res.send({err: 0, msg: '登錄ok', token: token})
            } else {
                res.send({err: -2, msg: '用戶名或密碼不正確'})
            }
            // console.log(data)
        })
        .catch((err) => {
            return res.send({err: -1, msg: '內部錯誤'})
        })

})

 

app.use('/food', (req, res, next) => {
    console.log(req.body)
    let {token} = req.body
    JWT.checkToken(token)
        .then((data) => {
            next()
        })
        .catch((err) => {
            res.send({err: -998, msg: 'token 非法'})
        })
    // if(req.session.login){
    //     next()
    // }else{
    //     res.send({err:-999,msg:'請先登錄'})
    // }

}, fooodRouter)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM