cookie、session、token案例剖析

Cookie

我以前的文章有寫過,咱們知道在H5的本地存儲沒出來以前,前端須要存儲的數據基本用cookie來存儲,並且cookie能在服務端與瀏覽器之間進行數據傳送,當服務端把一些用戶信息返回給前端後,前端須要存起來,方便調用,可是他存的數據有限,只能存4k的數據量前端

cookie機制:node

cookie實際上是補充http協議的無狀態性的缺點,底層是經過服務器端在http響應消息中增長set-cookie字段來將cookie信息發送給瀏覽器端,由於它只能存4k,通常用來存瀏覽器的身份信息,瀏覽器在訪問服務器的某些資源的時候,會在http請求頭中將cookie數據傳給服務器,這樣服務器就知道是誰請求的了,可是若是用戶清除了cookie,那就啥都沒有啦...mysql

session

session是存在服務器端的,主要配合cookie完成瀏覽器的身份認證和狀態ajax

他相對於cookie較安全點,當用戶請求服務器的時候,服務器會把數據臨時存下來,若是退出網站後,session會被銷燬,sql

可是,若是架集羣的時候,也就是服務器作負載均衡的時候,session就不妙了,
此時的session就沒法共享,可能會提示你session無效,實際上是存在另一臺服務器上的,
固然也能夠放在數據庫中,可是不多有人這麼作,由於若是高併發的時候會不停地調數據庫 ,很麻煩,數據庫

因此通常不多把session存到內存或數據庫,若是有10000人登陸那麼會佔服務器或數據庫不少內存,可能會致使服務器崩掉.express

sessionId跟咱們編程不要緊 是服務端自動種下的,等到服務器把sessionId經過set-cookie傳給客戶端,客戶端會自動把sessionId在傳給服務器,編程

因此,現代的後端都是經過token來開發的...json

Token

Token 後端進行身份驗證的票據:後端

一、用戶登陸,發送用戶名、密碼
二、服務端收到後,進行驗證用戶名和密碼
三、驗證成功後,生成一個token票據,併發送給客戶端
四、客戶端得到token票據後,存儲起來,等到再次請求的時候,把token做爲參數傳給服務器
五、服務端收到到,對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)
     }
 })

好了,相信各位大兄弟姐妹理解的差很少了,若是有什麼見解,能夠私信,互相學習交流...

相關文章
相關標籤/搜索