什么Token?一文带你深入理解Token

743 阅读6分钟

上一篇主要和大家讲了session相关的内容,那这篇婧婧姐就跟大家聊聊token吧,主要从什么是 token,token的工作原理,NodeJS实现token以及token的优缺点去给大家讲解。

前言

1.Token的引入

以登录功能为例,传统的方式是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,此方式会造成服务器极大压力,在这样的背景下,token便应运而生。

2.Token的定义

token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个token,便将此token返回给客户端,以后客户端只需带上这个token前来请求数据即可,无需再次带上用户名和密码。

3.使用Token的目的

token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。

Token的工作原理

1.Token如何存储用户状态

基于token的身份验证是无状态的,我们不是将用户信息存储在服务器或者session中,而是直接把用户信息加密成token子串直接返回给客户端,客户端把token字段存储在客户端的本地存储(localStorage)即可。

2.Token的工作流程

1.客户端 向 服务端 发送登录HTTP请求,把用户名和密码发送给服务端。

2.服务端接收到客户端的登录请求,去数据库查询用户,登录验证成功,并返回一个签名的token给客户端。

3.客户端接收到服务端返回的token,把token存储在localStorage中,且用于每次发送的HTTP请求。

4.服务端接收到请求就会验证客户端携带过来的token,验证整个返回数据,否则返回未登录状态。

3.Token 的组成

token由三部分组成:

第一部分(header):声明加密算法。

第二部分(payload载荷):保存用户信息。

第三部分(signature签名):需要base64转码后的payload连接组成的字符串,然后通过header中声明的加密方式进行加密。

当然为了防止被人伪造篡改token,我们也可以随机加一段字符串秘钥进行混淆。

NodeJS实现Token

NodeJS生成token验证需要使用 jsonwebtoken 模块

1.安装

npm install jsonwebtoken --save

2.导入

// index.jsconst express=require("express");const jwt = require('jsonwebtoken');let app = express()// token的秘钥let secret = 'shfgeurij34y8u2p3'

3.登录成功,生成Token 令牌

app.post('/login',async (req, res) => {   let { username, password } = req.body;   let data = await db.query(`select * from user where username='${username}' and password='${password}';`);   if (data.length == 0) {       res.send({           code: 400,           msg:'用户名或者秘密错误'      })       return  }   let info = {       ...data[0]  }   // 登录成功 生成token令牌   // jwt.sign()   // 三个参数:参数1:payload 用户相关信息,参数2:秘钥,参数3:一个对象,过期时间,创建token的时间,或者token的idlet token =  jwt.sign(info, secret, {            //Token有效时间 单位s           // 单位可以是 '10h' '7 days'           expiresIn: 60 * 60 * 10,        })   res.send({       code: 200,       msg: '登录成功',       token  })})

把生成的token令牌当成响应体返回给客户端,客户端把token令牌存储到localStorage中。

4.验证Token

每次发送请求都会把localStorage 中 token信息携带在请求头中的 authorization 传递给 后端。

后端数据中直接通过req.headers.authorizatio 来获取即可,然后使用jwt.verify() 来验证对应的token。

app.get('/getlist',(req, res) => {   // 在req.headers.authorization 中获取传递过来的token   let token = req.headers.authorization;   // 使用jwt.verify()来验证token   jwt.verify(token, secret, (error, decoded) => {       // error 就是验证token错误的信息       if (error) {           res.send({               code: 400,               msg:'未登录'          })           return      }       // decoded 解密之后的token       res.send({           msg:'请求成功'      })  })})

5.设置白名单统一验证Token

什么是白名单:即不需要做用户验证的接口。

一个网站中不是所有的数据接口都必须验证用户是否登录,很多数据接口为未登录的情况下也是可以正常请求,那么这一类型的数据接口 就可以设置为白名单。

比如:电商网站,商品列表就不需要登录也可以请求。

我们可以在所有的接口之前对session进行验证,也可以称之为session拦截。

// 登录接口不需要验证tokenlet white = ['/login','/register'];// 设置统一验证token// 就不需要每一个接口一个接口单独去验证server.use((req, res, next) => {   // 获取req.url 来判断是否在白名单中 如果在白名单中 不需要验证token   if (white.includes(req.url)) {       next();       return  }   // 获取token来验证   let token = req.headers.authorization;   jwt.verify(token, secret, (error, decoded) => {       if (error) {           res.send({               code: 400,               msg:'未登录'          })           return      }       //decoded.info 用户相关的信息       // 把 用户信息 存到req中,方便其他接口获取用户信息       req.info = decoded.info;       next()  })})// /user 不需要再验证,因为已经统一验证过了app.get("/user", (req, res) => {   // req.info 获取从token验证出来的信息   res.send('返回正常的数据')});

Token的优缺点

优点

session身份验证也有自己的优缺点,那么token也不例外,那婧婧姐就先给大家聊聊token的优点吧。

  • 防止CSRF 攻击:Session 验证是基于(cookie 中的 session_id)是由浏览器自动携带发送到服务端的,借助这个特性,攻击者就可以通过让用户误点攻击链接,达到攻击效果。而 token 是通过客户端本身逻辑作为动态参数加到请求中的,token 也不会轻易泄露出去,因此 token 在 CSRF 防御方面存在天然优势。

  • 无状态、可扩展 :服务器只是生成token , 然后验证token,基于这种无状态和不存储Session信息,负载负载均衡器能够将用户信息从一个服务传到其他服务器上。

  • 单点登录友好:使用 session 进行身份认证的话,实现单点登录,需要我们把用户的 session 信息保存在一台电脑上,并且还会遇到常见的 cookie 跨域的问题。但是,使用 token 进行认证的话, token 被保存在客户端,不会存在这些问题。.

  • 项目应用更广泛:cookie不支持移动端,session需要依赖cookie,但是token不用。

缺点

接下来在来聊聊token的缺点。

  • 占宽带:token加密字串,正常情况下要比session_id更大,需要消耗更多流量,挤占更多带宽。

  • 无状态:token 的无状态,导致了它最大的缺点:当后端在token 有效期内用户Logout或者更改它的权限的话,不会立即生效,如果没有增加额外的处理逻辑,则一般需要等到有效期过后才可以。

结合上一篇的session,那么token和session的区别以及各自的优缺点和用法应该就一目了然了,每家公司使用的验证方式都不一样,最好的办法就是都会,赶紧学起来吧,毕竟技多不压身嘛!