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

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

什么是先后端分离?为何要先后端分离?

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

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

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

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

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

看到这里,先后端分离被普遍应用也能够理解了。json

你们须要注意,并非全部的项目都须要先后端分离,像是大型的项目,开发人员不少,人员分工明确,这种团队配置下,使用先后端分离可增长工做效率提升系统质量。可是团队人员少,分工不那么明确的状况下,再采用先后端分离的架构,只会增长开发成本和系统复杂度。先后端分离是一个好的架构思路,可是须要看具体的业务和人员状况,切勿盲目的跟从。后端

先后端分离经常使用的认证方式

先后端分离中先后端的交互是经过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端外还有移动端;
  • 临时的受权需求;
  • 纯后端系统之间的交互。

本文围绕先后端分离这个话题总结分享了先后端分离时的认证方案。这些仅仅是通用的通常方案,在具体的业务场景中,还有不少不典型的扩展的验证方案也是极好的,欢迎你们留言讨论本身心中的最佳认证方案。

参考及扩展阅读