美文网首页
jwt介绍,以及在node和koa中的应用

jwt介绍,以及在node和koa中的应用

作者: 小小了墨 | 来源:发表于2019-08-16 10:34 被阅读0次

    JWT

    JSON Web Token( JWT)是目前最流行的跨域认证解决方案。

    一般的跨域认证方式

    流程如下:

    1. 客户端向服务器发送用户名和密码
    2. 服务器验证通过后,在session中保存相关数据
    3. 服务器向客户端返回一个session_token放到cookie中
    4. 客户端每次请求都通过cookie携带session_token
    5. 服务器拿到session_token,通过这个找到以前存的用户信息,进行判断

    上面session中存放的数据,通过数据库或者别的持久化操作存储,但是会存在服务器集群数据同步的问题,处理起来比较麻烦。

    JWT原理

    服务器拿到用户登录信息,验证通过后会根据用户信息去生成一个Token并携带Signature返回给用户,服务器不存储session的信息,交由用户去存储。

    JWT组成

    xxxxx.yyyyy.zzzzz对应的依次如下

    • Header
    • Payload
    • Signature

    中间通过.分隔:Header.Payload.Signature

    Header

    使用的是Base64URL 算法转成字符串,解析后是个JSON对象,描述JWT的元数据

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

    Payload

    使用的是Base64URL 算法转成字符串,解析后是个JSON对象,存放JWT需要传输的信息

    • iss 签发人
    • exp 过期时间
    • sub 主体信息
    • iat 签发时间
    • aud 受众
    • nbf 生效时间
    • jti 编号

    注意,JWT 默认是不加密的,任何人都可以读到,所以不要把重要信息放在这个部分。

    Signature

    使用你需要的加密方式(默认HMAC SHA256加密)

    HMACSHA256(base64UrlEncode(Header) + "." +base64UrlEncode(Payload),secret)
    

    JWT客户端发送

    客户端收到服务器返回的Token,存储在cookie、sessionStorage或者localStorage中

    在需要认证的时候,将Token添加到Http请求的Header中

    Header: {
        Authorization: `Bearer ${Token}`
    }
    

    注意, Bearer和Token之间有个空格

    在node中使用jwt

    node-jsonwebtoken

    jsonwebtoken是JWT的node版本 github

    1. 安装
    yarn add jsonwebtoken
    
    1. 生成Token
    const jwt = require('jsonwebtoken')
    
    const token = jwt.sign({
        // 设置一个小时的过期时间   
        exp: Math.floor(Date.now() / 1000) + 3600,
        // 自定义的携带信息
        data: {
            name: user.name,
            createTime: user.createTime
        }
    }, 'demo')
    
    1. JWT验证
    jwt.verify(token, 'demo', (err, decode) => {
        // decode是携带的信息
        if (err) {
        // 认证失败
        // ...    
        } else {
        // 成功
        // ...
        }
    })
    
    1. 路由权限验证

    由于本人使用的是koa搭建的服务端,所以下面是基于koa的操作

    const koa = require('koa')
    const Router = require('koa-router')
    const bodyParser = require('koa-bodyparser')
    const jwtKoa = require('koa-jwt')
    
    const app = new koa()
    const router = new Router()
    
    app.use(bodyParser())
    
    // JWT拦截
    
    /**
     * secret是服务端存储的密钥
     * unless是不做JWT验证的条件
     * unless.method 不做验证的请求方式 这里是所有的GET请求不去做拦截
     * unless.path 不做验证的请求路径 这里是/login请求不去做拦截
     *
    */
    
    // 特殊路径处理,这里的login用的是post
    const specialPath = new RegExp(`^\/login`)
    app.use(jwtKoa({ secret: 'demo' }).unless({ method: ['GET'], path: [specialPath] }))
    
    
    router.get('/demo',(ctx, next) => {
        
    })
    router.post('/demo', (ctx, next) => {
        
    })
    router.del('/demo/:id', (ctx, next) => {
        
    })
    router.put('/demo/:id',(ctx, next) => {
        
    })
    
    app.use(router.routes()).use(router.allowedMethods())
    

    jsonwebtoken 文档

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

    • 异步:如果提供回调,则使用err或JWT 调用回调。

    • 同步:将JsonWebToken返回为字符串。

    payload

    payload 必须是一个object, buffer或者string。注意, exp只有当payload是object字面量时才可以设置

    如果payload不是buffer或string,它将被强制转换为使用的字符串JSON.stringify()。

    secretOrPrivateKey

    secretOrPrivateKey 是包含HMAC算法的密钥或RSA和ECDSA的PEM编码私钥的string或buffer。

    options

    options:

    • algorithm:加密算法(默认值:HS256)
    • expiresIn:过期时间, 以秒表示或描述时间跨度zeit / ms的字符串。如60,"2 days","10h","7d"
    • notBefore:生效时间, 以秒表示或描述时间跨度zeit / ms的字符串。如:60,"2days","10h","7d"
    • audience:受众
    • issuer:签发人
    • jwtid:编号
    • subject:主体
    • noTimestamp
    • header

    在expiresIn,notBefore,audience,subject,issuer没有默认值时。也可以直接在payload中用exp,nbf,aud,sub和iss分别表示,但是你不能在这两个地方同时设置。

    生成的jwts通常会默认包含一个iat值除非指定了noTimestamp。

    jwt.sign({
      exp: Math.floor(Date.now() / 1000) + (60 * 60),
      data: '一个小时过期'
    }, 'demo')
    // 或者
    jwt.sign({
      data: '一个小时过期'
    }, 'demo', { expiresIn: '1h' });
    
    

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

    用法和jwt.sign差不多,用来验证token的合法性

    jwt.decode(token [,options])

    返回解码没有验证签名是否有效的payload, 用来获取payload

    参考链接:JSON Web Token 入门教程
    jsonwebtoken文档jwt.iogithub: node-jsonwebtoken

    相关文章

      网友评论

          本文标题:jwt介绍,以及在node和koa中的应用

          本文链接:https://www.haomeiwen.com/subject/lthfsctx.html