面试官:登录功能是怎么实现的?(上)

在平时的面试中,对于工作年限不长的同学,我比较喜欢问:“说说你们系统中是怎么维护登录态的?”,“还有其他的方式实现登录吗?”等问题,主要考察大家对登录常用技术方案的了解。

登录鉴权是互联网信息交互中常见的话题,我们会分两篇文章,介绍几种常用的登录方案:

  • Cookie + Session 登录

  • Token 登录

  • SSO 单点登录

  • OAuth 第三方登录

  • 扫码登录

  • 一键登录

今天先来介绍 Cookie + Session 登录Token 登录以及SSO 单点登录


一、Cookie + Session 登录

大家都知道,HTTP 是一种无状态的协议。

无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送 HTTP 请求之后,服务器根据请求返回数据,但不会记录任何信息。

为了解决 HTTP 无状态的问题,出现了 Cookie。

Cookie 是服务器端发送给客户端的一段特殊信息,这些信息以文本的方式存放在客户端,客户端每次向服务器端发送请求时都会带上这些特殊信息。

在 B/S 系统中,登录功能通常都是基于 Cookie 来实现的。当用户登录成功后,服务端会将登录状态记录到 Session 中,同时需要在客户端保存一些信息(SessionId),并要求客户端在之后的每次请求中携带它们。

在这样的场景下,使用 Cookie 无疑是最方便的,因此我们一般都会将 SessionId 保存到 Cookie 中,当服务端收到请求后,通过验证 Cookie 中的 SessionId 来判断用户的登录信息。

Cookie + Session 实现流程

Cookie + Session 的登录方式是目前最经典的一种登录方式,现在仍然有大量的场景在使用。

具体可以采用以下步骤:

  • 用户输入用户名和密码,前端将用户提交的用户名和密码发送到后端进行验证。

  • 后端验证用户信息是否正确,并创建一个SessionSession是一种服务器端保存用户会话信息的机制,用于识别多次请求之间的逻辑关系。

  • 后端将Session ID(通常是一个随机的字符串)返回给前端,并通过 Cookie 的方式将Session ID保存在浏览器中。这样就可以保证当用户再次发送请求时,后端可以通过该 Session ID 来识别用户身份,并完成相关的操作。

  • 在后续的请求中,浏览器会自动将保存的 Cookie 信息发送到后端进行验证,如果 Session ID有效,则返回相应的数据。如果 Session ID 失效或者不存在,则需要重新登录获取新的 Session ID

  • 在用户退出时,后端需要删除对应的 Session 信息,以保证安全性。

需要注意的是,CookieSession 方案也存在一些安全问题。例如,如果攻击者可以获取到 Cookie 信息,则可以模拟用户身份进行恶意操作。因此,在实现时需要考虑添加一些安全措施,如:

  • 使用 HTTPS 协议来加密通信内容,防止中间人攻击。

  • 设置 Cookie 的 HttpOnly 属性为 true,以防止脚本获取到 Cookie 信息。

  • 尽量减少 Session 的有效期,以避免 Session 被盗用的风险。

  • 在前端和后端均验证用户身份,防止伪造登录请求。

Cookie + Session 的缺点

当然,它也存在一些缺点:

  • 安全性问题:由于 Session ID 存储在 Cookie 中,如果攻击者获取到该 Cookie 信息,则可以模拟用户身份进行恶意操作。为了解决这个问题,需要采取一些安全措施,如使用 HTTPS 协议加密通信内容、设置 CookieHttpOnly 属性为 true 等。

  • 跨域问题:由于 Cookie 只能在同域名下共享,因此跨域访问时无法访问到对应的 Cookie 信息。这时,可能需要采用一些其他的跨域解决方案,如 JSONP、CORS 等。

  • 扩展性问题:由于 Session 信息存储在服务器端,当系统扩展到多台服务器时,需要采用一些集中式的 Session 管理方案,否则会出现 Session 不一致或者丢失等问题。

  • 性能问题:由于 Session 信息存储在服务器端,因此每次请求都需要从服务器读取 Session 信息,这可能会导致性能问题。为了解决这个问题,可以采用一些缓存方案来提高访问速度。

  • 一些移动设备和浏览器可能会禁用 CookieSession 机制,这会导致无法正常登录。


二、Token 登录

为了解决 Cookie + Session 机制暴露出的诸多问题,我们可以使用 Token 的登录方式。

Token 是通过服务端生成的一串字符串,以作为客户端请求的一个令牌。当第一次登录后,服务器会生成一个 Token 并返回给客户端,客户端后续访问时,只需带上这个 Token 即可完成身份认证。

Token 机制实现流程

Token 登录方案是一种常用的前后端分离技术,具体流程如下:

  • 用户输入用户名和密码,前端将用户提交的用户名和密码发送到后端进行验证。

  • 后端验证用户信息是否正确,并生成一个 Token。Token 是一串加密的字符串,包含了用户的身份信息和权限等相关信息。

  • 后端将 Token 返回给前端,并保存在客户端的LocalStorage或者SessionStorage中。

  • 每次向后端发送请求时,前端都需要在请求头部携带 Token 信息。

  • 后端接收到请求后会从 Token 中解析出用户身份信息,并通过权限校验等操作来判断请求是否合法。

  • 如果校验通过,则返回相应的数据,否则返回错误信息。

  • 在用户退出时,前端需要删除保存的 Token 信息。

需要注意的是,由于 Token 信息存储在客户端,因此不同于 Session 机制,它可以轻松地跨域使用,而且不需要考虑 Session 共享、分布式管理等问题。同时,由于 Token 机制不依赖服务器端的资源,因此在大规模高并发访问时,它具有更好的性能表现。

然而,由于 Token 信息存储在客户端,因此存在一定的安全风险,例如 Token 被盗用、被篡改等问题。为了保证安全性,需要采取一些安全措施,如:

  • 使用 HTTPS 协议来加密通信内容,防止中间人攻击。

  • 设置 Token 的过期时间,以避免 Token 长时间存储在客户端而被恶意利用。

  • 在前端和后端均验证 Token 信息,防止伪造登录请求。

  • 根据实际需求对 Token 进行加密处理,以增加破解难度。

Token 生成方式

Token 的生成方式通常有以下几种:

  • 随机字符串:可以使用一些随机数生成算法,如 UUID、Snowflake 等来生成一个随机的字符串作为 Token。由于随机字符串本身就是随机分布的,因此具有很高的安全性。

  • JWT(JSON Web Token):JWT 是一种基于 JSON 格式的开放标准(RFC 7519),用于在多方之间安全地传输信息。它将用户身份信息和权限等相关信息编码成一个 JSON 对象,并通过数字签名或者加密等方式进行验证和保护。JWT 除了可以用于 Token 登录外,还可以用于 API 认证、单点登录等场景。

  • Hash 值:可以将用户身份信息和时间戳等参数通过某种散列函数计算出一个 Hash 值,并将该 Hash 值作为 Token 返回给客户端。由于 Hash 值具有不可逆性和唯一性,因此也具有较高的安全性。

无论采用哪种方式生成 Token,都需要结合实际业务场景和安全需求来选择,并且需要对 Token 进行加密或者数字签名等操作来保障其安全性。同时,在 Token 的过期时间、密钥管理、Token 注销等方面都需要考虑相应的安全措施。

Token 登录的缺点

  • 安全性问题:由于 Token 存储在客户端,因此存在被盗用、伪造、篡改等风险。为了解决这个问题,需要采取一些安全措施,如使用 HTTPS 协议加密通信、设置 Token 的过期时间和加密、数字签名等操作。

  • 线程安全问题:由于 Token 无状态,因此不支持同步机制,可能存在线程安全问题。例如,当同时有多个请求同时使用相同的 Token 时,可能会导致重复登录等问题。

  • 扩展性问题:由于 Token 信息存储在客户端,因此对于大规模分布式系统而言,如果需要多台服务器之间共享 Token,则需要采用一些集中式的 Token 管理方案。

  • 依赖前端处理:由于 Token 存储在客户端,因此需要前端代码来处理 Token 信息的存储和发送,这增加了前端代码的复杂度和维护成本。

  • Token 泄露问题:由于 Token 是长期有效的,一旦被泄露,则会存在更长时间的安全风险。为了避免这个问题,需要对 Token 进行定期更新或者注销等操作。


三、SSO 单点登录

SSO(Single Sign-On,单点登录)是一种在多个应用程序(比如 Web 服务)中实现认证和授权的方法。它允许用户只需登录一次,就可以访问多个应用程序,大大提高了用户体验和工作效率。

SSO 的基本流程

  • 用户通过浏览器访问第一个应用程序,并输入用户名和密码进行登录。

  • 第一个应用程序验证用户信息后,生成一个 Token 并将该 Token 返回给浏览器端。同时,它会将 Token 与该用户的身份信息绑定并存储在一个共享的认证数据源中,如 LDAP、数据库等。

  • 用户再次访问另一个应用程序时,该应用程序检查用户是否已经登录过。如果用户未登录,则引导用户到第一个应用程序进行登录;如果用户已经登录,则从共享的认证数据源中获取用户的身份信息,并生成一个新的 Token 返回给浏览器端。

  • 浏览器将 Token 发送给第二个应用程序,第二个应用程序使用相同的认证数据源来验证 Token,以确认该用户是否有权限访问该应用程序。

  • 如果 Token 有效,则第二个应用程序返回相应的数据;否则,它要求用户重新进行登录或者提示用户无权访问。

  • 用户访问其他应用程序时,重复上述过程。

SSO 的实现方式

  • 基于 Cookie 实现

该实现方式将 Token 存储在 Cookie 中,并通过浏览器的同源策略来共享 Token 信息。由于 Cookie 只能在同域名下共享,因此该方式仅适用于同域名下的应用程序。

  • 基于 Session 实现

该实现方式将 Token 信息存储在服务器端的 Session 中,并通过 Session ID 来共享 Token 信息。由于 Session 机制通常需要依赖某种中心化的 Session 管理系统,因此实现较为复杂。

  • 认证中心

认证中心就是一个专门负责处理登录请求的独立的 Web 服务。用户统一在认证中心进行登录,登录成功后,认证中心记录用户的登录状态,并将 Token 写入 Cookie。(注意这个 Cookie 是认证中心的,应用系统是访问不到的)。

应用系统检查当前请求有没有 Token,如果没有,说明用户在当前系统中尚未登录,那么就将页面跳转至认证中心进行登录。由于这个操作会将认证中心的 Cookie 自动带过去,因此,认证中心能够根据 Cookie 知道用户是否已经登录过了。如果认证中心发现用户尚未登录,则返回登录页面,等待用户登录,如果发现用户已经登录过了,就不会让用户再次登录了,而是会跳转回目标 URL ,并在跳转前生成一个 Token,拼接在目标 URL 的后面,回传给目标应用系统。

应用系统拿到 Token 之后,还需要向认证中心确认下 Token 的合法性,防止用户伪造。确认无误后,应用系统记录用户的登录状态,并将 Token 写入 Cookie,然后给本次访问放行。(这个 Cookie 是当前应用系统的,其他应用系统是访问不到的)当用户再次访问当前应用系统时,就会自动带上这个 Token,应用系统验证 Token 发现用户已登录,于是就不会有认证中心什么事了。

此种实现方式相对复杂,支持跨域,扩展性好,是单点登录的标准做法。

  • 基于 OAuth 实现

该实现方式采用 OAuth 协议来实现用户身份验证和授权。OAuth 是一个开放标准,用于在不同域名下的应用程序之间安全地共享资源和授权访问。该实现方式具有良好的兼容性和可扩展性,但需要额外的授权服务器和令牌管理机制。

  • 基于 OpenID Connect 实现

该实现方式是在 OAuth2.0 协议上构建的一个开放标准,用于实现用户身份验证和授权。它继承了 OAuth 的优点,并提供了更丰富的身份认证和授权机制。该实现方式具有较高的兼容性和安全性,但需要额外的授权服务器和令牌管理机制。

SSO 单点登录退出

  • 单点注销:该方式是指用户在任一应用程序中进行注销操作时,可以自动将其他应用程序中的会话和相关信息一并清除。这通常需要使用回调 URL 和 Token 等机制来实现。

  • 局部注销:该方式是指用户只在当前应用程序中进行注销操作,并不会影响其他应用程序。在局部注销后,用户需要重新输入用户名和密码才能再次访问该应用程序。

  • 全局注销:该方式是指用户在某个应用程序中进行注销操作,可以清除所有应用程序中的会话和相关信息。这通常需要采用集中式的 Token 管理机制,并需要对 Token 进行撤销或者更新等操作。

SSO 单点登录的缺点

  • 单点故障:由于单点登录系统需要负责所有应用程序的身份认证和授权,一旦发生故障或被攻击,则会影响所有应用程序的正常运行。

  • 安全问题:由于单点登录系统涉及到多个应用程序的身份认证和授权,因此安全性问题尤为重要。如果认证系统遭受攻击,则可能导致多个应用程序的信息泄露或数据损坏。

  • 中心化依赖:由于单点登录系统是集中式的,因此对于大规模分布式系统而言,如果需要多台服务器之间共享认证信息,则需要采用一些集中式的认证管理方案。

  • 可扩展性问题:由于单点登录系统需要处理多个应用程序之间的身份认证和授权,因此在实现时需要考虑其可扩展性问题。例如,在增加新的应用程序时,单点登录系统需要进行相关配置和调整,以保证其正常运行。

  • 维护成本:由于单点登录系统需要负责多个应用程序的身份认证和授权,因此其维护和管理成本相对较高。例如,在增加新的应用程序或更改现有应用程序时,需要对单点登录系统进行相应的调整和测试,以确保其正常运行。


总结

Cookie + SessionTokenSSO单点登录是常见的身份认证和授权方案,它们各有特点:

  • Cookie + Session:该方案通常用于同一域名下的应用程序之间的身份认证。它通过浏览器的 Cookie 和服务器端的 Session 机制来共享用户信息和状态,但需要注意的是,由于 Cookie 和 Session 都是存储在客户端或服务端的,因此可能存在被盗用或篡改的风险。

  • Token:该方案通常用于跨域身份认证和授权。它通过生成加密签名的 Token 来代表用户身份和权限,并将 Token 传递给其他应用程序进行验证。相比于 Cookie + Session 方案,Token 方案更加安全可靠,但也需要注意 Token 的有效性和安全性等问题。

  • SSO 单点登录:该方案通常用于多个应用程序之间的身份认证和授权。它通过引入认证中心来统一管理用户身份和权限,从而避免了重复登录和重复授权的问题。相比于 Cookie + Session 和 Token 方案,SSO 单点登录方案更加便捷和高效,但同时也存在单点故障和安全问题等风险。

需要注意的是,根据具体业务需求和安全要求,可以选择不同的身份认证和授权方案,并在实现时结合一些安全措施来保障用户信息的安全性。同时,在使用 Token 和 SSO 单点登录方案时,还需要对 Token 和认证中心进行管理和维护,以保证其正常运行和可靠性。

最后

给大家留一个思考题:PC 端的扫码登录,是如何实现的呢?

如果你现在正在找工作,可以私信“web”或者直接添加下方小助理进群领取前端面试小册、简历优化修改、大厂内推以及更多阿里、字节大厂面试真题合集,和p8大佬一起交流。

猜你喜欢

转载自blog.csdn.net/Likestarr/article/details/135415285