cookie、session、token案例剖析

Cookie

我之前的文章有写过,我们知道在H5的本地存储没出来之前,前端需要存储的数据基本用cookie来存储,而且cookie能在服务端与浏览器之间进行数据传送,当服务端把一些用户信息返回给前端后,前端需要存起来,方便调用,但是他存的数据有限,只能存4k的数据量

cookie机制:

cookie其实是补充http协议的无状态性的缺点,底层是通过服务器端在http响应消息中增加set-cookie字段来将cookie信息发送给浏览器端,因为它只能存4k,一般用来存浏览器的身份信息,浏览器在访问服务器的某些资源的时候,会在http请求头中将cookie数据传给服务器,这样服务器就知道是谁请求的了,但是如果用户清除了cookie,那就啥都没有啦...

session

session是存在服务器端的,主要配合cookie完成浏览器的身份认证和状态

他相对于cookie较安全点,当用户请求服务器的时候,服务器会把数据临时存下来,如果退出网站后,session会被销毁,

但是,如果架集群的时候,也就是服务器做负载均衡的时候,session就不妙了,
此时的session就无法共享,可能会提示你session无效,其实是存在另外一台服务器上的,
当然也可以放在数据库中,但是很少有人这么做,因为如果高并发的时候会不停地调数据库 ,很麻烦,

所以一般很少把session存到内存或数据库,如果有10000人登录那么会占服务器或数据库很多内存,可能会导致服务器崩掉.

sessionId跟我们编程没关系 是服务端自动种下的,等到服务器把sessionId通过set-cookie传给客户端,客户端会自动把sessionId在传给服务器,

所以,现代的后端都是通过token来开发的...

Token

Token 后端进行身份验证的票据:

1、用户登录,发送用户名、密码
2、服务端收到后,进行验证用户名和密码
3、验证成功后,生成一个token票据,并发送给客户端
4、客户端获得token票据后,存储起来,等到再次请求的时候,把token作为参数传给服务器
5、服务端收到到,对token进行验证,成功后进行业务处理,不成功则提示信息失效

token可以存到数据库中,如果同一个账号在不同的机器A,B进行登录,A先登录,保存了了一个token,B机器在登录的时候,会把该用户的token删除重新生成,那么A机器的用户token失效,等到再次请求的时候,带着失效的token去查询数据库,查不到,就登录失效了。重新登录

例如我们做一个例子: nodejs + express + mysql
首先,我们本地连接数据库

var mysql = require('mysql');
//查询 传入查询条件 和 回调函数
const select = function(){
    var connection = mysql.createConnection({
        host : 'localhost',
        user : 'root',
        password: '',
        database: 'testToken'
    });
    
    connection.connect();     //连接数据库
    connection.query(sql,callback);  //业务处理
    connection.end()    //断开与数据库的连接
    
}
//添加
const insert = function(sql,params,callback){
    var connection = mysql.createConnection({
        host : 'localhost',
        user : 'root',
        password: '',
        database: 'testToken'
    });
    
    connection.connect();
    var query = connection.query(sql,params,callback)
    connection.end()
}

//暴露
module.exports = {
    select,
    insert
}

然后我们设置路由,并生成token,进行业务处理

var express = require('express')
var md5 = require('md5')
var router = express.Router();
var dbtools = require('./mysql/dbtools.js')

var queryCon = `select * from users where username='${req.query.username}' and psw='${req.query.psw}'`
router.get('/api/login', function(req, res, next) {
    dbtools.select(queryCon,function(err, result){
        if(err){
            console.log(err)
            return;
        }
        console.log(result);
        if(result){
            var token = md5(new Date().getTime())
            
            //如果用户token存在,把这个用户的token需要先删除....
            dbtools.insert('INSERT INTO token SET ? ',{username: req.query.username, token: token },
                function(err) {
                      if(!err) {
                          res.json({username: req.query.username, token: token});
                      }
                  }
            )
        }else{
            res.send('登录失败')
        }
    })
})

module.exports = router;

回调地狱啊,改造改造...

router.get('/api/login', saveUserInfo);
const saveUserInfo = function(req, res, next){
    return new Promise(function(resolve, reject){
        dbtools.select(`select * from users where username='${req.query.username}' and psw='${req.query.psw}'`,
        function(err, results){
            if(err) {
                console.log(err);
                return;
            }
            if(results){
                resolve(res, req)
            }else{
                res.send('登录失败')
            }
        })
    })
}

saveUserInfo.then(function(res, req){
    var token = md5(new Date().getTime());
    dbtools.insert("INSERT INTO token SET ?", {username: req.query.username, token: token },
        function(err) {
            if(!err) {
                res.json({username: req.query.username, token: token});
            }
        }
    )
})


module.exports = router;

此时打开浏览器测试 http:localhost:8080/api/login?username='abc'&psw='123'
返回{username: 'abc',token:98763394034384kdijghya78fd9fd9fd}

最后,我们把获取的token保存下来,等的请求时放到http的请求头中

例如:
 $.ajax({
     url: '/api/user/',
     data: username,
     header: {'Accept': 'aplication/json','Authorization':token}
     success:function(res){
         console.log(res)
     }
 })  
 
 

好了,相信各位大兄弟姐妹理解的差不多了,如果有什么看法,可以私信,互相学习交流...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值