Nodejs——身份证验证

身份验证

HTTP 是一种没有状态的协议,也就是它并不知道是谁访问。客户端用户名密码通过了身份验证,不过下回这个客户端再发送请求时候,还得再验证

session

思想

1、客户端用户名跟密码请求登录
2、服务端收到请求,去库验证用户名与密码
3、验证成功后,服务端种一个cookie或发一个字符到客户端,同时服务器保留一份session
4、客户端收到 响应 以后可以把收到的字符存到cookie
5、客户端每次向服务端请求资源的cookie会自动携带
6、服务端收到请求,然后去验证cookie和session,如果验证成功,就向客户端返回请求的库数据

Session存储位置: 服务器内存,磁盘,或者数据库里

Session存储内容: id,存储时间,用户名等说明一下登录的用户是谁

客户端携带 : cookie自动带,localStorage手动带

如何保存信息给浏览器

前端种:

cookie/localstorage

后端种:

  • 服务器给浏览器种cookie: cookie-parser

    服务器给浏览器种cookie的同时在服务器上生成seesion: cookie-session

cookie-session

安装引入

let cookieSession = require('cookie-session')

Nodejs——身份证验证_第1张图片
配置中间件

app.use(cookieSession({
	name:'保存到服务器的session的名字',
  keys:[必传参数,代表加密层级],
  maxAge:1000 //保留cookie的时间
}))

种cookie,备份session
Nodejs——身份证验证_第2张图片

req.session.key=value

读cookie对比session
Nodejs——身份证验证_第3张图片

req.session.key  返回true

删除cokkie、session
Nodejs——身份证验证_第4张图片

delete req.session.key 
req.session.key = undefined

具体代码如下:

let express = require("express")
let cookieSession = require("cookie-session")

// 搭建服务器
let app = express()

// 静态资源托管
app.use(express.static("./public"))

// 监听端口
app.listen(3000)

// 使用中间件cookieSession
app.use(cookieSession({
    keys: ["aa", "bb", "cc"],//加密层级
    maxAge:1000*30 //cookie的失效时间
}))

// 验证用户身份
app.get("/api/login", (req, res) => {
    // 1.验证客户端传递来的用户名密码和数据库是否一样
    // 给用户端中cookie,并且同时和服务端留一份session
    // console.log(req.session);
    req.session.nz = "userId"
    // 后端种完后给后端返回数据
    res.send({
        err: 0,
        msg: "登录成功!",
        data: {
            username: "张三丰"
        }
    })
})

// 自动登录功能
app.get("/api/user", (req, res) => {
     //读cookie对比session
    //如果前端传递来的cookie是有效的,那么req.session.nz1906的值就是“userId"
    //如果前端传递来的cookie失效了,那么req.session.nz1906的值就是undefined
    let pass = req.session.nz //如果用户登录了,那么pass="userId",如果用户cookie失效或者没有,那么返回null
    if(pass){
        //用户身份一直存在的,取库数据,并且返回
        res.send({
            erro:0,
            data:"/api/user的数据!!!"
        })
    }else{
        res.send({
            err:1,
            data:"请先登录账号或登录过期"
        })
    }
    res.end()
})

// 注销登录
app.get("/api/logout",(req,res)=>{

    //删除服务端session和客户端的cookie
    req.session.nz = undefined
    res.end()
})

token

思想

在服务端不需要存储用户的登录记录,全部发给客户端有客户端自己存(cookie,local)

1、客户端使用用户名跟密码请求登录
2、服务端收到请求,去验证用户名与密码
3、验证成功后,服务端会签发一个 Token(加了密的字符串),再把这个 Token 发送给客户端
4、客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
5、客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
6、服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

实现

jsonwebtoken的安装引入

let jwt = require('jsonwebtoken')

在这里插入图片描述
生成签名

let token = jwt.sign(payload, secretOrPrivateKey, [options, callback])

Nodejs——身份证验证_第5张图片

校验token

jwt.verify(token, secretOrPublicKey, [options, callback])

Nodejs——身份证验证_第6张图片

  • token: 制作后的token
    secretOrPublicKey: 解密规则,字符串,或者公钥
    callback: 回调 err 错误信息 decode 成功后的信息
    options: expiresIn 过期时间
    Nodejs——身份证验证_第7张图片
    token删除

由客户端,负责删除

token讲解具体代码如下

let express = require("express")

let app = express()

// 插入中间件
let bodyParser = require("body-parser")

// 引入jsonwebtoken模块
let jwt = require("jsonwebtoken")

app.listen(3000, () => console.log("3000端口正在接听。。。"))

// 使用中间件
app.use(bodyParser())

// 请求登录,服务端生成token令牌
app.get("/api/login", (req, res) => {
    // 获取前端传过来的username,password进行数据库的验证
    // 生成token令牌
    let token = jwt.sign({
        username: req.query.username
    }, "nz",{expiresIn:60}) //expiresIn cookie失效时间,按照秒计算
    // 将token和库信息返回前端
    res.send({
        err: 0,
        msg: "登录成功",
        data: "数据库",
        token
    })
})

// 验证toknn
app.get("/api/user", (req, res) => {
    // 获取客户端传递的token
    // 数据库放在 地址栏上面 || 非地址栏上面 || 请求头上面
    let token = req.query.token || req.body.token || req.headers.token;
    // 验证token
    jwt.verify(token, "nz", (err, decode) => {
        // console.log("err",err); //null代表没有报错
        console.log("decode",decode);
        if (err) {
            //报错说明用户信息验证失败
            res.send({
                err: 1,
                msg: "登录失败,token失效"
            })

        } else {
            // 验证成功
            // 数据返回给前端
            res.send({
                err: 0,
                msg: "登录成功",
                data: "数据库"
            })
        }
    })
})

session 与 token 的区别

session token
服务端保存用户信息 ×
避免CSRF攻击 ×
安装性 一般
多服务器粘性问题 存在 不存在

多服务器粘性问题

当在应用中进行 session的读,写或者删除操作时,会有一个文件操作发生在操作系统的temp 文件夹下,至少在第一次时。假设有多台服务器并且 session 在第一台服务上创建。当你再次发送请求并且这个请求落在另一台服务器上,session 信息并不存在并且会获得一个“未认证”的响应。我知道,你可以通过一个粘性 session 解决这个问题。然而,在基于 token 的认证中,这个问题很自然就被解决了。没有粘性 session 的问题,因为在每个发送到服务器的请求中这个请求的 token 都会被拦截

家中逆战,无畏疫情,武汉加油,中国加油,人类必胜!!!

你可能感兴趣的:(cookie,nodejs,session)