基于JWT用户认证方式(前后端分离)

 基于JWT的用户认证方式

  在前后端开发时为什么需要用户认证呢?原因是由于HTTP协定是不存储状态的,这意味着当我们透过账号密码验证一个使用者时,当下一个request请求时他就把刚刚的资料忘记了。于是我们的程序就不知道谁是谁了。 所以为了保证系统的安全,就需要验证用户是否处于登陆状态。

传统方式

  

  最简单的方式是:前端登录,后端根据用户信息生成一个token,并保存这个token和对应的用户id到数据或者session当中,接着把token传给用户,存入浏览器cookie,之后浏览器在请求时都会带上这个cokie,后端根据cookie值来查询用户,验证是否过期。

  但是这样做页面会出现XSS漏洞,由于cookie可以被javaScript读取,XSS漏洞会导致用户token泄漏,而作为后端识别的标识,这样做是很不安全的。尽管可以进行转义输出内容,但谁也不能保证在大型项目中不会出现这个问题。

Json Web Token(JWT) 

  JWT是一个开放标准,它定义了一张用于简洁,自包含用于通信双方之间以JSON对象的形式安全传递的方法。JWT可以使用HMAC算法或者RSA的公钥密钥来进行签名。它具有两个特点:

  • 简洁

    •   可以通过URL,POST参数或者在HTTP header放松,因为数据量小,传输速度快
  • 自包含
    •   负载中包含了所有用户所需要的信息,避免了多次查询数据库

 JWT组成

  • Header头部

    •   包含了两个部分,token类型和采用加密算法
{
  "alg": "HS256",
  "typ": "JWT"
}

它会使用 Base64 编码组成 JWT 结构的第一部分,如果你使用Node.js,可以用Node.js的包base64url来得到这个字符串。

  • Payload负载

    •   这部分就是存放信息的地方,例如可以把用户ID等信息存放在这里,面对这部分有进行详细比较,常用的由iss(签发者),exp(过期时间),sub(面向的用户),aud(接收方),iat(签发时间)。
    • {
          "iss": "lion1ou JWT",
          "iat": 1441593502,
          "exp": 1441594722,
          "aud": "www.example.com",
          "sub": "[email protected]"
      }
    • 他会使用Base64编码组成第二部分
  • Signature签名 
    •   前两部分使用Base64编码的,即前端可以解开知道里面的信息。Signature需要使用编码后的header和payload以及我们提供的一个密钥,然后使用header中指定的算法进行签名。签名的作用是保证JWT没有被篡改过。
    • 三部分通过“.”连接在一起就是JWT了,他可能是这个样子,长度和加密的算法和私钥有关系。
    • eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjU3ZmVmMTY0ZTU0YWY2NGZmYzUzZGJkNSIsInhzcmYiOiI0ZWE1YzUwOGE2NTY2ZTc2MjQwNTQzZjhmZWIwNmZkNDU3Nzc3YmUzOTU0OWM0MDE2NDM2YWZkYTY1ZDIzMzBlIiwiaWF0IjoxNDc2NDI3OTMzfQ.PA3QjeyZSUh7H0GfE0vJaKW4LjKJuC3dVLQiY4hii8s
    • 你可能会想,HTTP请求总带上token,这个token传来传去占用不必要的宽带资源。如果这么想了,就可以了解下HTTP2,他对头部进行了压缩,解决了这个问题。
  • 签名的目的 
    • 进行签名是为了防止内容被篡改。如果有人对头部以及负载的内容解码时之后进行了修改,再进行编码,最后加上之前的签名组合形成新的JWT的话,那么服务端会判断出新的头部和负载形成的签名和JWT附带上的签名是不一样的。如果对新的头部和负载进行签名,在不知道服务器加密时用的密钥的话,的出来的签名是不一样的。
  • 信息暴露 
    • Base64只是一种编码,是可以进行逆转的,因此敏感的数据是不适合放入到token当中的,他适合传递一些非敏感信息。JWT经常用于用户认证和授权系统,甚至可以实现单点登录。
  • 总结 
    • JWT是由三部分组成

      • 加密的算法和token的类型
      • 用户信息(id,过期时间)
      • 签名
    • 这并不会对数据进行保护,使用这种方式只是为了防止内容被篡改,还有就是减少服务器的压力(不需要在数据库的查询)。

JWT使用

  1. 首先,前端通过Web表单将自己的用户名和密码发送到后端的接口。这一过程一般是一个HTTP POST请求。建议的方式是通过SSL加密的传输(https协议),从而避免敏感信息被嗅探。
  2. 后端核对用户名和密码成功后,将用户的id等其他信息作为JWT Payload(负载),将其与头部分别进行Base64编码拼接后签名,形成一个JWT。形成的JWT就是一个形同lll.zzz.xxx的字符串。
  3. 后端将JWT字符串作为登录成功的返回结果返回给前端。前端可以将返回的结果保存在localStorage或sessionStorage上,退出登录时前端删除保存的JWT即可。
  4. 前端在每次请求时将JWT放入HTTP Header中的Authorization位。(解决XSS和XSRF问题)
  5. 后端检查是否存在,如存在验证JWT的有效性。例如,检查签名是否正确;检查Token是否过期;检查Token的接收方是否是自己(可选)。
  6. 验证通过后后端使用JWT中包含的用户信息进行其他逻辑操作,返回相应结果。

和Session方式存储id的差异

Session方式存储用户id的最大弊病在于Session是存储在服务器端的,所以需要占用大量服务器内存,对于较大型应用而言可能还要保存许多的状态。一般而言,大型应用还需要借助一些KV数据库和一系列缓存机制来实现Session的存储。

而JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。除了用户id之外,还可以存储其他的和用户相关的信息,例如该用户是否是管理员、用户所在的分组等。虽说JWT方式让服务器有一些计算压力(例如加密、编码和解码),但是这些压力相比磁盘存储而言可能就不算什么了。具体是否采用,需要在不同场景下用数据说话。

  • 单点登录  

Session方式来存储用户id,一开始用户的Session只会存储在一台服务器上。对于有多个子域名的站点,每个子域名至少会对应一台不同的服务器,例如:www.taobao.comnv.taobao.comnz.taobao.comlogin.taobao.com。所以如果要实现在login.taobao.com登录后,在其他的子域名下依然可以取到Session,这要求我们在多台服务器上同步Session。使用JWT的方式则没有这个问题的存在,因为用户的状态已经被传送到了客户端。

总结

JWT的主要作用在于(一)可附带用户信息,后端直接通过JWT获取相关信息。(二)使用本地保存,通过HTTP Header中的Authorization位提交验证。但其实关于JWT存放到哪里一直有很多讨论,有人说存放到本地存储,有人说存 cookie。

原文地址:https://www.cnblogs.com/qybk/p/10965069.html

时间: 2024-10-06 10:06:19

基于JWT用户认证方式(前后端分离)的相关文章

基于Electron+.NET Core的前后端分离的跨平台桌面应用

Web做界面比原生桌面界面开发速度真心要快很多,而且组件也多. 分析: 1..NET Core和Electron都是跨平台的. 2.NET Core做后端很方便,但是没有GUI,Electron做桌面应用很方便,但是存在Node.js单线程跑CPU密集计算的弱点. 灵感: 那Electron启动后,调用NET Core程序运行在后台,作为本地后端,CPU密集计算直接扔给后端跑不就得了? 甚至于说,能不能Electron只负责展示层,NET Core负责所有的业务逻辑? 已知: NET Core通

前后端分离之JWT用户认证

在前后端分离开发时为什么需要用户认证呢?原因是由于HTTP协定是不储存状态的(stateless),这意味着当我们透过帐号密码验证一个使用者时,当下一个request请求时它就把刚刚的资料忘了.于是我们的程序就不知道谁是谁,就要再验证一次.所以为了保证系统安全,我们就需要验证用户否处于登录状态. 传统方式 前后端分离通过Restful API进行数据交互时,如何验证用户的登录信息及权限.在原来的项目中,使用的是最传统也是最简单的方式,前端登录,后端根据用户信息生成一个token,并保存这个 to

前后端分离,认证框架分析

跨域安全访问API oauth2是一种用户授权标准,jwt是传递token的一种消息标准,shiro是一个授权框架 1.JWT JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,用于作为JSON对象在各方之间安全地传输信息.该信息可以被验证和信任,因为它是数字签名的. 加密.解密.开发包等,请参考官网:https://jwt.io/ <JWT token破解绕过> <前后端分离之JWT用户认证> <认识JWT>

一套基于SpringBoot+Vue+Shiro 前后端分离 开发的代码生成器

一.前言 最近花了一个月时间完成了一套基于Spring Boot+Vue+Shiro前后端分离的代码生成器,目前项目代码已基本完成 止步传统CRUD,进阶代码优化: 该项目可根据数据库字段动态生成 controller.mapper.service.html.jsp.vue.php..py ... 等各种类型代码,采用 velocity 模板引擎在页面动态配置生成代码,前后端动态权限配置,前端权限精确到 按钮 级别,后端权限精确到 uri 上,QQ授权第三方单用户登录...等 基本环境: JDK

七个开源的 Spring Boot 前后端分离项目,一定要收藏!

前后端分离已经在慢慢走进各公司的技术栈,根据松哥了解到的消息,不少公司都已经切换到这个技术栈上面了.即使贵司目前没有切换到这个技术栈上面,松哥也非常建议大家学习一下前后端分离开发,以免在公司干了两三年,SSH 框架用的滚瓜烂熟,出来却发现自己依然没有任何优势! 其实前后端分离本身并不难,后段提供接口,前端做数据展示,关键是这种思想.很多人做惯了前后端不分的开发,在做前后端分离的时候,很容易带进来一些前后端不分时候的开发思路,结果做出来的产品不伦不类,因此松哥这里给大家整理了几个开源的前后端分离项

SSM前后端分离/不分离对比Demo

之前某些原因,整理了一个小的Demo,用于演示.个人认为在SSM前后端不分离的基础上在前端处理上比较麻烦一点之后就是注解的使用.总结一些对比,仅是自己掌握的,不够严谨,不足之处请大佬批评指正. 路由控制:前后端分离的情况后端在任何都会返回一个json数据,不涉及路由处理,即页面跳转全是由前端自己完成.不分离的情况,路由跳转一般由后端完成,而且携带数据,通过重定向或请求转发实现,依赖Servlet中的内置对象. 返回数据:前后端分离的情况后端返回的整体划分上只有执行逻辑响应的消息实体类和对应的需要

从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之七使用JWT生成Token(个人见解)

在 上一篇中讲到了在NetCore项目中如何进行全局的请求模型验证,只要在请求模型中加了验证特性,接口使用时只用将数据拿来使用,而不用去关系数据是否符合业务需求. 这篇中将讲些个人对于JWT的看法和使用,在网上也能找到很多相关资料和如何使用,基本都是直接嵌到  Startup 类中来单独使用.而博主是将jwt当做一个验证方法来使用.使用起来更加方便,并且在做验证时也更加的灵活. 1.什么是JWT? Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON

Aspnet前后端分离项目手记(二)关于token认证

在前后端分离的项目中,首先我们要解决的问题就是身份认证 以往的时候,我们使用cookie+session,或者只用cookie来保持会话. 一,先来复习一下cookie和session 首先我们来复习一下在aspnet中cookie和session的关系,做一个简单试验 这是一个普通的view没有任何处理 可以看到,没有任何东西(cookie),然后当我们写入一个session之后 \ 会发现多了一个名为ASP.NET_SessionId的cookie.我们都知道在aspnet中,session

Aspnet Mvc 前后端分离项目手记(二)关于token认证

在前后端分离的项目中,首先我们要解决的问题就是身份认证 以往的时候,我们使用cookie+session,或者只用cookie来保持会话. 一,先来复习一下cookie和session 首先我们来复习一下在aspnet中cookie和session的关系,做一个简单试验 这是一个普通的view没有任何处理 可以看到,没有任何东西(cookie),然后当我们写入一个session之后 会发现多了一个名为ASP.NET_SessionId的cookie.我们都知道在aspnet中,session是保