谈谈前后端分离及认证选择

标签: 前后端分离 jwt | 发表时间:2020-09-24 14:49 | 作者:DeanWu
出处:https://segmentfault.com/blogs

前几年,web开发领域中「前后端分离」比较火,现如今已逐渐成为事实标准。但是究竟什么是前后端分离?又为什么要前后端分离呢?

什么是前后端分离?为什么要前后端分离?

前后端分离,说的更多的是一种架构上的概念。在传统的web架构中,比如经典的MVC,会分数据层、逻辑层、视图层。这个视图层即我们所说的前端了,映射到代码层面,就是html、js、css等代码文件。数据层和逻辑层更多的是后端部分,例如我们的 .java.go.py等文件。这些文件会在一个工程中,并不会单独的开发、测试、部署。

在前后端分离的架构中,前端和后端是分开的,分别在不同的工程中。前端有专门的前端开发人员来进行开发、测试,后端则有后端开发人员来进行开发、测试,他们之间通过API来交互。

前后端分离有这么几个好处:

1/ 解耦了前后端的工作人员 让前端和后端分别交给更擅长的人来做,细化了工种,可以更加的专精。前端人员来关心用户体验、UI设计、交互渲染;后端人员更关注业务逻辑、性能保障、安全等方面。在项目进度方面,前后端可以并行开发,而互不影响,加快了整体的项目进度。

2/ 解耦了前后端的代码 后端只需提供API服务,不再与静态文件交互。后端可以使用更复杂的分布式、微服务架构,提供更好的性能和稳定性保障。同时前端除了PC端之外,移动端也可以使用相同的一套后端服务。

看到这里,前后端分离被广泛应用也可以理解了。

大家需要注意,并不是所有的项目都需要前后端分离,像是大型的项目,开发人员很多,人员分工明确,这种团队配置下,使用前后端分离可增加工作效率提高系统质量。但是团队人员少,分工不那么明确的情况下,再采用前后端分离的架构,只会增加开发成本和系统复杂度。前后端分离是一个好的架构思路,但是需要看具体的业务和人员情况,切勿盲目的跟从。

前后端分离常用的认证方式

前后端分离中前后端的交互是通过API进行的,那么其中的认证是少不了的。前后端分离中常用的认证方式有下面几种:

  • Session-Cookie
  • Token 验证
  • OAuth(开放授权)

Session-Cookie 方式

Session-Cookie 方式是我们开发web应用时最常用的认证方式。它的认证过程一般是这样的:

  • 1/ 用户浏览器向服务器发起认证请求,将用户名和密码发送给服务器。
  • 2/ 服务器认证用户名和密码,若通过则创建一个session对话,并将用户信息保存到session中。session的信息可以是保存到服务器文件、共享外部存储、数据库等存储中,等下次请求时查询验证使用。
  • 3/ 服务器会将该session的唯一标识ID,返回给用户浏览器,并保存在cookie中。
  • 4/ 用户请求其他页面时,浏览器会自动将用户的cookie携带上,并发起接口请求,服务端收到请求后,从cookie解析出sessionID, 根据这个sessionID 查询登录后并保存好的session,若有则说明用户已登录,放行。

该方式是MVC架构中最常用的认证方案,在前后端分离中也是可以用的。几乎所有的Web框架都默认集成了Session-Cookie的认证方式,而且对Session-Cookie方式的安全性和稳定性方面都有很成熟的处理方案。

当前端代码使用后端web框架当做web容器驱动时,Session-Cookie 方案可作为首选的认证方案。

Token 方式

Token 方式是不同系统交互、前后端架构常用的认证方式。Token 方式的认证流程如下:

  • 1/ 用户使用用户名和密码登录,将用户名和密码发送给服务器。
  • 2/ 服务器验证用户名和密码,若正确,则签发token,返回给用户。
  • 3/ 用户收到token后,将其存储起来,web服务一般为localStrage 或cookie。
  • 4/ 用户请求其他资源页面时,会携带token,一般放到header 或参数中,发送给服务端。
  • 5/ 服务器收到后,验证token,判断用户的正确性。

JWT(JSON Web Token)是最常用的一种Token认证方式,已成为Token认证的标准事实。JWT 方式将Token 分段,使其可以保持少量数据,还增加了签名验证,确保了token的安全性。JWT 网上介绍的资料很多,这里不再赘述。不了解的,可参考下边这些资料:

OAuth 方式

OAuth(Open Authorization)是一个开放标准,允许用户授权第三方网站访问他们存储在服务端的用户信息。我们常见的的QQ、微信等第三方登录便是Auth认证方式。OAuth协议有1.0和2.0两个版本。相比较1.0版,2.0版整个授权验证流程更简单更安全,也是目前最主要的用户身份验证和授权方式。

OAuth更像是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用。

在单纯的前后端分离系统中,OAuth并不是常用的方式,它更多的应用在不同系统之间的授权交互。

对比思考

刨去不常用的OAuth,这里对比两种前两种常用的认证方式 JWT Auth 和 Session-Cookie Auth ,到底谁才是前后端分离认证的最佳实践呢。从下面几个方向分析比对。

可扩展性

Session-Cookie 是 有状态的服务,在服务端保存了session的信息。当服务端扩容的时候,需要考虑到session的共享问题,这个问题已有成熟的解决放方案,可使用session复制、共享、持久化等方式解决,大多数的分布式Web框架已经集成了处理方案。JWT 验证方式是 无状态的服务,服务端可随意扩缩容。

Session-Cookie 方式 基于Cookie,也就是必须是浏览器或支持Cookie的浏览器封装的框架,纯移动端无法使用。JWT 不同, 不依赖Cookie, 只要在本地可存储即可。

安全性

Web开发中常见的两个安全问题 XSS(跨站点脚本攻击) 和 CRSF (跨站点请求伪造)。前者利用注入脚本到用户认证网站上,执行恶意脚本代码。后者则利用浏览器访问后端自动携带cookie的机制,来跨站伪造请求。XSS 只要我们对注入端,进行过滤、转义就能解决,CRSF 是我们重点关注的。

在Session-Cookie认证方式中,因为把SessionID保存在了Cookie中,很容易引起CRSF攻击。在大多数的WEB框架中有集成解决方案,如Django 的csrftoken 、Beego的xsrfToken 等。在使用Session-Cookie方案时建议开启web框架的csrf功能。

JWT 认证,可以把Token存放在Cookie或localstorage。建议存在localstorage,这样就彻底避免了 CRSF 攻击。

另外JWT有几个安全性的问题,需要注意:

  • 1/ JWT是明文编码 JWT 的编码是明文Base64的一个编码,是可以反编译的。在使用JWT传输信息的时候,不要放置重要敏感信息,最好使用https。
  • 2/ JWT 泄露问题 解决JWT的泄露问题是一个平衡的问题。有三种处理方式由轻到重,看你业务重要性酌情选择:

    • 将JWT 的过期时间设置的很短,即使泄露也无关紧要。
    • 在服务端设计JWT的黑名单机制,将泄露的Token 加黑名单即可。
    • 保存签发的JWT,当JWT泄露时,直接设置失效。

性能

Session-Cookie方案,因为后端服务存储了Session信息,在认证的时候需要查询,当有大量认证的时候是非常耗费资源的。JWT 可以把信息放到token中,只需要验证解码,使用签名验证token即可,相对来说效率会有提升。

从上面三个方面,我们分析了Session-Cookie和JWT 方式各自的优缺点,和面对问题的一些应对方案。相信大家会有自己的心里选择。

抛开业务场景谈技术都是耍流氓。不同的业务场景,不同的架构设计,适用的认证方式也是不同的。这里按我自己的经验总结了下,什么情况下该使用那种认证方式,大家可参考。

适用Session-Cookie认证方案的情况:

  • 项目只有web端的情况;
  • 项目人员配置少,且前后端开发都会参与;
  • 项目前后端分离不彻底,前端使用后端web框架作为服务容器启动;

使用 JWT 认证方案的情况:

  • 项目人员配置充足,分工明确;
  • 项目除web端外还有移动端;
  • 临时的授权需求;
  • 纯后端系统之间的交互。

本文围绕前后端分离这个话题总结分享了前后端分离时的认证方案。这些仅仅是通用的一般方案,在具体的业务场景中,还有很多不典型的扩展的验证方案也是极好的,欢迎大家留言讨论自己心中的最佳认证方案。

参考及扩展阅读

相关 [后端 分离 认证] 推荐:

谈谈前后端分离及认证选择

- - SegmentFault 最新的文章
前几年,web开发领域中「前后端分离」比较火,现如今已逐渐成为事实标准. 前后端分离,说的更多的是一种架构上的概念. 在传统的web架构中,比如经典的MVC,会分数据层、逻辑层、视图层. 这个视图层即我们所说的前端了,映射到代码层面,就是html、js、css等代码文件. 数据层和逻辑层更多的是后端部分,例如我们的 .java 、 .go、 .py等文件.

前后端分离了,然后呢?

- - ITeye资讯频道
前后端分离已经是业界所共识的一种开发/部署模式了. 关于前后端开发的另一个讨论可以参考这里. 即使通过API来解耦前端和后端开发过程,前后端通过RESTFul的接口来通信,前端的静态内容和后端的动态计算分别开发,分别部署,集成仍然是一个绕不开的问题 — 前端/后端的应用都可以独立的运行,但是集成起来却不工作.

前后端分离的优缺点

- - Web前端 - ITeye博客
WEB 前后端分离三个最大的优点在于:1:最大的好处就是前端JS可以做很大部分的数据处理工作,对服务器的压力减小到最小2:后台错误不会直接反映到前台,错误接秒较为友好3:由于后台是很难去探知前台页面的分布情况,而这又是JS的强项,而JS又是无法独立和服务器进行通讯的. 所以单单用后台去控制整体页面,又或者只靠JS完成效果,都会难度加大,前后台各尽其职可以最大程度的减少开发难度.

实现前后端分离的心得

- - 文章 – 伯乐在线
对目前的web来说,前后端分离已经变得越来越流行了,越来越多的企业/网站都开始往这个方向靠拢. 那么,为什么要选择前后端分离呢. 前后端分离对实际开发有什么好处呢?. 在以前传统的网站开发中,前端一般扮演的只是切图的工作,只是简单地将UI设计师提供的原型图实现成静态的HTML页面,而具体的页面交互逻辑,比如与后台的数据交互工作等,可能都是由后台的开发人员来实现的,或者是前端是紧紧的耦合后台.

前后端分离接口规范

- -
随着互联网的高速发展,前端页面的展示、交互体验越来越灵活、炫丽,响应体验也要求越来越高,后端服务的高并发、高可用、高性能、高扩展等特性的要求也愈加苛刻,从而导致前后端研发各自专注于自己擅长的领域深耕细作. 然而带来的另一个问题:前后端的对接界面双方却关注甚少,没有任何接口约定规范情况下各自干各自的,导致我们在产品项目开发过程中,前后端的接口联调对接工作量占比在30%-50%左右,甚至会更高.

前后端分离的陷阱 (insights.thoughtworks.cn)

- - IT瘾-jianshu
不管你设计的系统架构是怎么样,最后都是你的组织内的沟通结构胜出. 这个观点一直在组织内不断地被证明,但也不断地被忽略. 近几年,随着微服务架构风格的引入、前后端生态的快速发展、多端产品化的出现,前后端分离已经成为行业的普遍实践,也是大型企业级分布式架构的缺省选择. 前后端分离也给软件技术人员的职业发展和协作方式带来了新的变化,分别出现了前端工程师、后端工程师、前端开发团队以及后端开发团队.

前后端分离的思考与实践(四)

- - TaoBaoUED
前后端分离模式下的安全解决方案. 在前后端分离的开发模式中,从开发的角色和职能上来讲,一个最明显的变化就是:以往传统中,只负责浏览器环境中开发的前端同学,需要涉猎到服务端层面,编写服务端代码. 而摆在面前的一个基础性问题就是. 本文就在前后端分离模式的架构下,针对前端在Web开发中,所遇到的安全问题以及应对措施和注意事项,并提出解决方案.

前后端分离的思考与实践(五)

- - TaoBaoUED
近年来各站点基于 Web 的多终端适配进行得如火如荼,行业间也发展出依赖各种技术的解决方案. 有如基于浏览器原生 CSS3 Media Query 的响应式设计、基于云端智能重排的「云适配」方案等. 本文则主要探讨在前后端分离基础下的多终端适配方案. 关于前后端分离的方案,在 《前后端分离的思考与实践(一)》中有非常清晰的解释.

前后端分离的思考与实践(六)

- - TaoBaoUED
Nginx + Node.js + Java 的软件栈部署实践. 关于前后端分享的思考,我们已经有五篇文章阐述思路与设计. 收藏夹将 Node.js 引入传统技术栈的具体实践. 淘宝网线上应用的传统软件栈结构为 Nginx + Velocity + Java,即:. 在这个体系中,Nginx 将请求转发给 Java 应用,后者处理完事务,再将数据用 Velocity 模板渲染成最终的页面.

前后端完全分离之API设计

- - ITeye资讯频道
API就是开发者使用的界面. 我的目标不仅是能用,而且好用, 跨平台(PC, Android, IOS, etc…)使用:本文将详细介绍API的设计及异常处理,并将异常信息进行封装友好地反馈给前端. 上篇文章前后端完全分离初探只是讲了些宽泛的概念,接下来的文章将直接上干货,干货的源码会挂在github上.