最近在做一个项目的技术选型,在认证方案和数据库选择上有点纠结,认证方案在传统的Session和JWT之间犹豫,数据库在MySQL和PostgreSQL之间纠结,相信很多人做技术选型的时候也会遇到类似的问题。今天就来聊聊这两个技术选型的问题,JWT令牌和传统Session认证到底该选哪个,PostgreSQL和MySQL相比有哪些特性,到底该选哪个,从原理、优缺点、适用场景等几个方面做一个详细的对比,希望能给正在做技术选型的朋友一些参考。
一、JWT令牌 vs 传统Session认证
先来说说认证方案的选择,JWT(JSON Web Token)这几年越来越火,很多新项目都在用JWT做认证,但是传统的Session认证也依然有很多人在用,两者各有优缺点,到底该选哪个呢?
1. 传统Session认证的原理和优缺点
传统的Session认证原理很简单:用户登录成功之后,服务器在Session里保存用户的登录信息,然后给客户端返回一个Session ID,客户端把Session ID存在Cookie里,后续请求的时候带上这个Session ID,服务器根据Session ID找到对应的Session,就能知道用户的登录状态。
Session认证的优点:
- 原理简单,容易理解和实现,几乎所有Web框架都内置支持。
- 服务端可以主动销毁Session,用户退出登录很方便,管理员也可以强制某个用户下线。
- Session数据存在服务端,比较安全,不容易被篡改。
- 可以存储比较多的用户信息,不只是用户ID,还可以存权限、角色、偏好等。
Session认证的缺点:
- Session存在服务端,占用服务器内存,用户量大了之后,服务器压力大,而且如果是多台服务器的话,需要做Session共享,比如用Redis存Session,增加了架构复杂度。
- 依赖Cookie,移动端或者跨域场景下,Cookie有时候不太好用,特别是跨域请求,需要处理CORS和Cookie的问题。
- 不利于分布式和微服务架构,Session共享比较麻烦,特别是多个服务之间,需要统一的Session管理。
- 移动端APP不太好用,APP没有Cookie机制,需要自己处理Session ID的存储和传递。
2. JWT认证的原理和优缺点
JWT(JSON Web Token)是一种开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于在各方之间安全地传输信息,信息以JSON对象的形式传输,可以通过数字签名验证和信任。
JWT的原理:用户登录成功之后,服务器生成一个JWT令牌,这个令牌包含了用户的信息(比如用户ID、用户名、过期时间等),并且用密钥签名,然后把令牌返回给客户端,客户端把令牌存起来(可以存在localStorage、sessionStorage或者Cookie里),后续请求的时候在Header里带上这个令牌,服务器验证令牌的签名,如果签名有效,就信任令牌里的用户信息,不需要再查数据库或者Session。
JWT的结构分为三部分:Header(头部,包含令牌类型和签名算法)、Payload(载荷,包含用户信息和过期时间等)、Signature(签名,用密钥对前两部分签名,防止篡改),三部分用点分隔,就是一个完整的JWT。
JWT的优点:
- 无状态,服务器不需要存储Session,令牌本身包含了用户信息,服务器只需要验证签名就行,不占用服务器内存,很容易水平扩展,适合分布式和微服务架构。
- 不依赖Cookie,可以用在任何客户端,Web、移动端APP、小程序都能用,跨域也很方便,只需要在Header里带令牌就行。
- 支持跨服务认证,多个服务之间可以共享同一个密钥,验证同一个令牌,不需要做Session共享,很适合微服务架构。
- 可以自定义Payload,在令牌里存储一些常用的用户信息,减少数据库查询。
JWT的缺点:
- 令牌一旦签发,在过期之前无法主动销毁,用户退出登录的时候,客户端删除令牌就行,但是令牌本身还是有效的,如果令牌泄露了,在过期之前别人都能用,除非做黑名单,但是做黑名单就又需要存储了,失去了无状态的优势。
- 令牌不能太大,因为Payload是Base64编码的,而且每次请求都要带,太大了会增加请求体积,所以不能在令牌里存太多信息。
- 安全性依赖于密钥的保护,如果密钥泄露了,别人就可以伪造任意用户的令牌,所以密钥一定要保管好,而且要足够复杂。
- 令牌里的信息是Base64编码的,不是加密的,任何人拿到令牌都能解码看到Payload里的信息,所以不要在JWT里存敏感信息,比如密码、手机号等。
3. 到底该选哪个?
总结一下,JWT和Session各有优缺点,没有绝对的好坏,关键是看你的场景:
- 如果是传统的Web应用,单体架构,用户量不大,用Session就够了,简单、成熟、可控,而且服务端可以主动销毁Session,安全性更好。
- 如果是分布式、微服务架构,或者需要支持移动端APP、小程序、跨域访问,或者用户量很大,需要水平扩展,那JWT更合适,无状态、易扩展、跨平台。
- 如果对安全性要求很高,需要能主动让用户下线,或者需要频繁修改用户权限,那Session更合适,因为JWT无法主动销毁,权限修改了也要等令牌过期才能生效。
- 也可以两者结合,比如用JWT做认证,但是用Redis做黑名单,或者JWT的有效期设短一点,配合Refresh Token,兼顾安全性和便利性。
我个人的建议是,新项目如果是前后端分离、需要支持移动端,或者是微服务架构,就用JWT,这是趋势,而且确实很方便。如果是传统的单体Web应用,用Session也没问题,成熟稳定。技术选型没有银弹,根据自己的实际场景选择最合适的就行。
二、PostgreSQL vs MySQL:PostgreSQL有哪些特性,到底该选哪个
再来说说数据库的选择,MySQL是最流行的开源关系型数据库,几乎所有人都用过,但是PostgreSQL这几年也越来越火,被称为"最强大的开源关系型数据库",很多人在新项目的时候会纠结,到底用MySQL还是PostgreSQL?今天就来聊聊PostgreSQL有哪些特性,和MySQL相比有什么优缺点,到底该选哪个。
1. PostgreSQL的强大特性
PostgreSQL是一个功能非常强大的开源关系型数据库,它的很多特性是MySQL没有的或者不如它的,这里列举几个最常用的:
丰富的数据类型:PostgreSQL支持很多高级数据类型,比如数组类型(可以存数组,还能对数组做查询)、JSON/JSONB类型(原生支持JSON,还能对JSON里的字段建索引,查询性能很好,比MySQL的JSON类型强大很多)、范围类型(可以存数值范围、时间范围,还能做范围查询和约束)、几何类型(点、线、圆、多边形等,支持空间查询)、UUID类型(原生支持UUID作为主键)等等,这些高级数据类型在很多场景下非常好用,能简化设计,提升性能。
强大的查询能力:PostgreSQL的SQL支持非常标准和强大,支持很多高级查询特性,比如窗口函数(Window Function,MySQL 8.0才支持,而且不如PostgreSQL强大)、公共表表达式(CTE,支持递归CTE)、全外连接(FULL OUTER JOIN,MySQL不支持)、交叉连接、自然连接等等,复杂查询用PostgreSQL写起来更方便,性能也更好。
完善的事务和并发控制:PostgreSQL的事务支持非常完善,支持事务的四个隔离级别(读未提交、读已提交、可重复读、串行化),而且实现了真正的串行化隔离级别(SSI,可串行化快照隔离),MySQL的InnoDB虽然也支持四个隔离级别,但是串行化隔离级别实现得不如PostgreSQL好。PostgreSQL的MVCC(多版本并发控制)实现也很优秀,读写不阻塞,并发性能很好。
强大的扩展能力:PostgreSQL有非常丰富的扩展(Extension),可以通过扩展增加各种功能,比如PostGIS(空间地理信息扩展,非常强大,做GIS相关的应用首选PostgreSQL+PostGIS)、pgcrypto(加密函数扩展)、uuid-ossp(UUID生成扩展)、hstore(键值对存储扩展)等等,而且你还可以自己写扩展,扩展能力非常强,这是MySQL比不了的。
优秀的性能和优化器:PostgreSQL的查询优化器非常强大,能生成非常高效的执行计划,特别是复杂查询、多表关联查询,PostgreSQL的性能往往比MySQL好。而且PostgreSQL支持并行查询、索引扫描、位图扫描、哈希连接、合并连接等多种优化手段,性能调优的空间很大。
其他特性:PostgreSQL还有很多其他优秀的特性,比如支持物化视图、支持部分索引、表达式索引、函数索引(MySQL 8.0才支持函数索引)、支持全文检索(内置全文检索功能,不需要额外用搜索引擎就能做简单的全文搜索)、支持触发器、存储过程、自定义函数(支持多种语言写函数,比如PL/pgSQL、Python、Perl等)等等,功能非常全面。
2. PostgreSQL的缺点
当然,PostgreSQL也不是完美的,它也有一些缺点:
- 学习曲线比MySQL陡,PostgreSQL的功能很多,概念也比较多,新手入门可能比MySQL难一点,特别是一些高级特性,需要花时间学习。
- 生态和社区不如MySQL,MySQL是最流行的开源数据库,用户量最大,生态最完善,各种工具、文档、教程、解决方案都很多,遇到问题很容易找到答案。PostgreSQL虽然也很流行,但是用户量和生态还是不如MySQL,特别是国内,MySQL的市场份额比PostgreSQL大很多。
- 复制和高可用方案不如MySQL成熟,MySQL的主从复制、读写分离、高可用方案(比如MHA、Orchestrator、InnoDB Cluster等)非常成熟,用的人也多。PostgreSQL的复制虽然也支持流复制、逻辑复制,但是高可用方案相对少一些,成熟度也不如MySQL,不过这几年也在快速发展,比如Patroni、repmgr等工具也越来越成熟了。
- 简单查询的性能可能不如MySQL,对于简单的查询、OLTP场景,MySQL的InnoDB性能很好,而且优化得很成熟,PostgreSQL在简单查询上可能不如MySQL快,但是在复杂查询、大数据量、数据分析场景下,PostgreSQL往往更强。
3. 到底该选哪个?
总结一下,MySQL和PostgreSQL各有优缺点,都是非常优秀的开源数据库,没有绝对的好坏,关键是看你的场景:
- 如果是普通的Web应用、OLTP场景、业务系统,团队熟悉MySQL,生态要求高,那选MySQL就对了,成熟、稳定、生态好、招人容易,大部分场景MySQL都能很好地满足。
- 如果是数据分析、数据仓库、复杂查询、GIS地理信息、需要JSON/数组等高级数据类型、需要强大的SQL支持,那PostgreSQL更合适,它的功能更强大,复杂查询性能更好,高级特性能大大简化开发。
- 如果是新项目,团队对两个数据库都熟悉,没有历史包袱,我个人更推荐PostgreSQL,因为它的功能更强大,更灵活,能应对更多的场景,而且这几年发展很快,越来越流行,未来的潜力很大。
- 也不用太纠结,这两个数据库都很优秀,大部分场景下都能满足需求,选哪个都不会错,关键是要用好,把数据库的特性发挥出来,做好索引、优化、运维,比选哪个数据库更重要。
我个人现在做新项目,如果没有特殊要求,一般会选PostgreSQL,因为它的JSONB类型、数组类型、强大的查询能力确实很好用,能简化很多设计,而且性能也很好。但是如果是维护老项目,或者团队都熟悉MySQL,那继续用MySQL也没问题,MySQL也在不断进步,8.0版本也增加了很多新特性,越来越强大了。
三、写在最后
JWT令牌 vs PostgreSQL特性:到底该选哪个。
以上就是我对这两个技术选型问题的分析和对比,JWT和Session各有优缺点,PostgreSQL和MySQL也各有千秋,没有绝对的好坏,也没有银弹,关键是根据自己的实际场景、团队情况、未来规划来选择最合适的技术。
技术选型是一件很重要的事情,选对了技术,能让开发事半功倍,系统稳定可靠;选错了技术,可能会遇到各种问题,后期维护成本很高,甚至要重构。但是技术选型也不用太纠结,没有完美的技术,每个技术都有它的适用场景,只要充分了解各个技术的优缺点,结合自己的实际情况,做出合理的选择就行。
而且,技术是不断发展的,今天的最佳实践,明天可能就过时了,所以也不用太追求完美,选一个当下合适的,能解决问题的,就够了。在使用的过程中,不断学习,不断优化,就算选的技术不是最完美的,也能用得很好。
最后用一句话结尾:"没有最好的技术,只有最合适的技术。"愿我们都能做出合理的技术选型,用合适的技术,解决实际的问题,做出优秀的产品。
评论(0)
暂无评论,快来抢沙发~
评论功能仅对会员开放,请先登录
登录