zoukankan      html  css  js  c++  java
  • 基于express框架的Token实现方案

    什么是Token?

    在计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思。一般我们所说的的token大多是指用于身份验证的token

    Token的特点

    • 随机性
    • 不可预测性
    • 时效性
    • 无状态、可扩展

    基于Token的身份验证方法

    • 客户端使用用户名和密码请求登录
    • 服务端收到请求,验证登录是否成功
    • 验证成功后,服务端会返回一个Token给客户端,反之,返回身份验证失败的信息
    • 客户端收到Token后把Token用一种方式(cookie/localstorage/sessionstorage/其他)存储起来
    • 客户端每次发起请求时都选哦将Token发给服务端
    • 服务端收到请求后,验证Token的合法性,合法就返回客户端所需数据,反之,返回验证失败的信息

    JWT(Json Web Tokens)

    生成Token的解决方案有许多,常用的一种就是 Json Web Tokens .

    JWT标准的Tokens由三部分组成

    1. header
    2. payload
    3. signature

    中间使用 " . " 分隔开,并且都会使用Base64编码方式编码,如下

    eyJhbGc6IkpXVCJ9.eyJpc3MiOiJCIsImVzg5NTU0NDUiLCJuYW1lnVlfQ.SwyHTf8AqKYMAJc

    header 部分主要是两部分内容,一个是 Token 的类型,另一个是使用的算法,比如下面类型就是 JWT,使用的算法是 Hash256。

    {
      "typ": "JWT",
      "alg": "HS256"
    }

    payload

    Payload 里面是 Token 的具体内容,这些内容里面有一些是标准字段,你也可以添加其它需要的内容。下面是标准字段:

    • iss:Issuer,发行者
    • sub:Subject,主题
    • aud:Audience,观众
    • exp:Expiration time,过期时间
    • nbf:Not before
    • iat:Issued at,发行时间
    • jti:JWT ID

    比如下面

    {
     "iss": "ninghao.net",
     "exp": "1438955445",
     "name": "wanghao",
     "admin": true
    }d

    signature

    JWT 的最后一部分是 Signature ,这部分内容有三个部分,先是拼接 Base64 编码的 header.payload ,再用不可逆的Hamc加密算法加密,加密时使用一个密钥,这个密钥服务端保存,生成signature。

    最后组合token,如下

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
    eyJpc3MiOiJuaW5naGFvLm5ldCIsImV4cCI6IjE0Mzg5NTU0NDUiLCJuYW1lIjoid2FuZ2hhbyIsImFkbWluIjp0cnVlfQ.
    SwyHTEx_RQppr97g4J5lKXtabJecpejuef8AqKYMAJc

    客户端收到这个 Token 以后把它存储下来,下回向服务端发送请求的时候就带着这个 Token 。服务端收到这个 Token ,然后进行验证,通过以后就会返回给客户端想要的资源。

    Nodejs实现

    token.js
    var crypto=require("crypto");
    var token={
        createToken:function(obj,timeout){
            console.log(parseInt(timeout)||0);
            var obj2={
                data:obj,//payload
                created:parseInt(Date.now()/1000),//token生成的时间的,单位秒
                exp:parseInt(timeout)||10//token有效期
            };
    
            //payload信息
            var base64Str=Buffer.from(JSON.stringify(obj2),"utf8").toString("base64");
    
            //添加签名,防篡改
            var secret="hel.h-five.com";
            var hash=crypto.createHmac('sha256',secret);
                hash.update(base64Str);
            var signature=hash.digest('base64');
    
    
            return  base64Str+"."+signature;
        },
        decodeToken:function(token){
    
            var decArr=token.split(".");
            if(decArr.length<2){
                //token不合法
                return false;
            }
    
            var payload={};
            //将payload json字符串 解析为对象
            try{
                payload=JSON.parse(Buffer.from(decArr[0],"base64").toString("utf8"));
            }catch(e){
                return false;
            }
    
            //检验签名
            var secret="hel.h-five.com";        
            var hash=crypto.createHmac('sha256',secret);
                hash.update(decArr[0]);
            var checkSignature=hash.digest('base64');
    
            return {
                payload:payload,
                signature:decArr[1],
                checkSignature:checkSignature
            }
        },
        checkToken:function(token){
            var resDecode=this.decodeToken(token);
            if(!resDecode){
    
                return false;
            }
    
            //是否过期
            var expState=(parseInt(Date.now()/1000)-parseInt(resDecode.payload.created))>parseInt(resDecode.payload.exp)?false:true;
            if(resDecode.signature===resDecode.checkSignature&&expState){
    
                return true;
            }
    
            return false;
        }
        
    }
    module.exports=exports=token;
  • 相关阅读:
    Linux-C基础知识学习:C语言作业-输入三角形底和高,输出三角形面积
    Linux-C基础知识学习:C语言作业-从键盘输入一个三位数,以逆序输出。例如输入456,输出654
    Linux基础知识学习:Linux下修改文件名或修改文件夹名称(有待解决问题)
    Linux基础知识学习:linux用命令重启
    Linux基础知识学习:linux用命令重启
    Linux基础知识学习:Linux中修改环境变量及使环境变量生效的方法
    Linux基础知识学习:Linux中修改环境变量及使环境变量生效的方法
    Linux基础知识学习:安装JDK出现 cannot execute binary file
    Linux基础知识学习:安装JDK(tar.gz)
    Linux基础知识学习:查看所使用的Linux系统是32位还是64 位的方法
  • 原文地址:https://www.cnblogs.com/axl234/p/7216300.html
Copyright © 2011-2022 走看看