身份验证(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)

 

posted @ 2020-07-01 11:49  CatherLee  阅读(905)  评论(0编辑  收藏  举报