小言_互联网的博客

Express中的session和token

266人阅读  评论(0)

Express身份验证

  • 在平常我们使用网站时,只需要登录一次即可,之后再访问这个网站就不需要再进行登录操作,本文将介绍Express中的session和token,它们是进行身份验证方法。
  • HTTP 是一种没有状态的协议,也就是它并不知道具体是谁,哪一个用户访问。客户端的用户名密码通过了身份验证,不过下回这个客户端再发送请求时,还需要再进行验证。
  • 本文的身份验证省略了在数据库中对比的操作,默认请求接口即为登录成功。

session

思想

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

代码

  • 1.初始化npm init -y
  • 2.安装引入expressnpm i express
  • 3.安装引入中间件cookie-sessionnpm i cookie-session
  • 4.配置中间件
  • 5.进行各种操作
    • 在客户端种cookie,备份sessionreq.session.key=value
    • 读cookie对比sessionreq.session.key 返回值为true 说明身份验证通过
    • 除cookie、sessiondelete req.session.key req.session.key = undefined
  • 6.模拟登录、验证、退出登录操作
// 引入express  和  cookie-session中间件
const express=require('express')
const cookieSession=require('cookie-session')

// 搭建服务器
const server=express()
// 静态资源托管    后面填写静态资源目录
server.use(express.static('./WWW'))
// 监听端口
server.listen(3000)


// 配置中间件
server.use(cookieSession({
    name:'mycookie',  //后端给前端种的cookie 名字       如果不写默认为 express:sess
    keys:['aaa'],//加密层级  一定要填写  否则报错
    maxAge:1000*30  //cookie的失效时间  毫秒为单位  30秒后失效
}))

// 设置登录接口  验证用户身份  登录成功后 在前端种 cookie
server.get('/api/login',(req,res)=>{
    // 1.检验客户端传来的用户名密码是否与数据库中的一致   省略步骤    默认正确
    // 2.给客户端种cookie   服务端保留一份session
    req.session.code='userId'
    // 3.后端种完cookie  给前端返回数据
    res.send({
        err:0,
        msg:'恭喜您,登录成功!',
        data:{
            username:'王富贵'
        }
    })
})



// 验证接口  判断用户是否登录  即验证cookie和session
server.get('/api/user',(req,res)=>{
    //如果  验证成功  返回  req.session.code 的值为  登录时设置的'userId'
    let pass=req.session.code
    if(pass){
        res.send({
            err:0,
            data:'用户已经登录',
        })
    }else{
        res.send({
            err:1,
            data:'用户未登录或登录过期了',
        })
    }
})


// 退出登录
server.get('/api/loginout',(req,res)=>{
    //两种方式  删除cookie,session

    delete req.session.code
    // req.session.code=undefined

    res.send({
        err:0,
        data:'退出登录成功'
    })
})

运行

  • 登录
  • 验证是否登录
  • 退出登录
  • 验证是否登录

token

思想

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

代码

  • 1.初始化npm init -y

  • 2.安装引入expressnpm i express

  • 3.安装引入中间件jsonwebtokennpm i jsonwebtoken

  • 4.配置中间件

  • 5.进行各种操作

    • 生成签名let token = jwt.sign(payload, secretOrPrivateKey, [options, callback])
      • payload: json 还有username,userid
      • secretOrPrivateKey: 加密规则,字符串,或者私钥path模块
      • options: 可选配置项
      • callback: 成功回调, 可选 返回制作后的token,也可同步返回
    • 校验token
      • jwt.verify(token, secretOrPublicKey, [options, callback])
      • token: 制作后的token
      • secretOrPublicKey: 解密规则,字符串,或者公钥
        -callback:回调 err 错误信息 decode 成功后的信息
      • options: expiresIn 过期时间
  • 6.模拟登录、验证、退出登录操作

const express=require('express')
//使用  req.body post的请求的数据   需要用到body-parser中间件
const bodyParser=require('body-parser')
//引入  jsonwebtoken模块
const jwt=require('jsonwebtoken')

const server=express()
server.use(express.static('./WWW'))
server.listen(3000)

// 使用中间件boy-parser
server.use(bodyParser())



// 登录   服务端生成token令牌
server.get('/api/login',(req,res)=>{
    // 1.获取用户名,密码进行数据库验证   默认成功
    // 2.生成token令牌  
    let token=jwt.sign({
        //前端传递的用户名
        username:req.query.username

        // 'aaa'加密规则  解密时也按照这个规则
    },'aaa',{
        //过期时间 以秒为单位
        // expiresIn:60   //  过期时间   60秒
    })

    // 3.将token传给前端  前端把存储起来
    res.send({
        err:0,
        msg:'登录成功',
        token
    })
})



// 验证登录
server.get('/api/user',(req,res)=>{
    //1.获得前端传递来的token     可以是get,post请求传递 也可以在请求头
    let token=req.query.token || req.body.token || req.headers.token;
    //2.token  检验token
    jwt.verify(token,'aaa',(err,decode)=>{
        console.log('err',err)  //null 表示没有报错
        console.log('decode',decode)
        if(!err){
            // 没有报错  数据返回给前端
            res.send({
                err:0,
                data:'用户登录成功'
            })
        }else{
            //报错  说明登录失败
            res.send({
                err:1,
                data:'登录失败,token失效了'
            })
        }
    })

    
})



// 退出登录
// 由前端操作  删除存储的  token

运行

  • 登录
  • 验证登录 将token放在req.query.token
  • 退出登录

session与token

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

转载:https://blog.csdn.net/k464746/article/details/104845520
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场