登录的实现方案有哪些?
登录鉴权是互联网信息交互中常见的话题,登录的实现方案有哪些呢?
常见的登录实现方案有一下几种:
- Cookie + Session 登录
- Token 登录
- SSO 单点登录
- OAuth 第三方登录
- 扫码登录
- 一键登录
Cookie + Session 登录
大家都知道,HTTP 是一种无状态的协议。
无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即我们给服务器发送 HTTP 请求之后,服务器根据请求返回数据,但不会记录任何信息。
为了解决 HTTP 无状态的问题,出现了 Cookie。
Cookie 是服务器端发送给客户端的一段特殊信息,这些信息以文本的方式存放在客户端,客户端每次向服务器端发送请求时都会带上这些特殊信息。
在 B/S 系统中,登录功能通常都是基于 Cookie
来实现的。
当用户登录成功后,服务端会将登录状态记录到 Session
中,同时需要在客户端保存一些信息(SessionId
),并要求客户端在之后的每次请求中携带它们。
在这样的场景下,使用 Cookie
无疑是最方便的,因此我们一般都会将 SessionId
保存到 Cookie
中,当服务端收到请求后,通过验证 Cookie
中的 SessionId
来判断用户的登录信息。
Cookie + Session 实现流程
Cookie
+ Session
的登录方式是目前最经典的一种登录方式,现在仍然有大量的场景在使用。
具体可以采用以下步骤:
- 用户输入用户名和密码,前端将用户提交的用户名和密码发送到后端进行验证。
- 后端验证用户信息是否正确,并创建一个
Session
。Session
是一种服务器端保存用户会话信息的机制,用于识别多次请求之间的逻辑关系。- 后端将
Session ID
(通常是一个随机的字符串)返回给前端,并通过 Cookie 的方式将Session ID
保存在浏览器中。这样就可以保证当用户再次发送请求时,后端可以通过该Session ID
来识别用户身份,并完成相关的操作。- 在后续的请求中,浏览器会自动将保存的
Cookie
信息发送到后端进行验证,如果Session ID
有效,则返回相应的数据。如果Session ID
失效或者不存在,则需要重新登录获取新的Session ID
。- 在用户退出时,后端需要删除对应的
Session
信息,以保证安全性。
需要注意的是,Cookie
和 Session
方案也存在一些安全问题。
例如,如果攻击者可以获取到 Cookie 信息,则可以模拟用户身份进行恶意操作。
因此,在实现时需要考虑添加一些安全措施,如:
- 使用 HTTPS 协议来加密通信内容,防止中间人攻击。
- 设置 Cookie 的
HttpOnly
属性为 true,以防止脚本获取到 Cookie 信息。 - 尽量减少 Session 的有效期,以避免 Session 被盗用的风险。
- 在前端和后端均验证用户身份,防止伪造登录请求。
Cookie + Session 的缺点
当然,它也存在一些缺点:
- 安全性问题:由于
Session ID
存储在Cookie
中,如果攻击者获取到该Cookie
信息,则可以模拟用户身份进行恶意操作。为了解决这个问题,需要采取一些安全措施,如使用HTTPS
协议加密通信内容、设置Cookie
的HttpOnly
属性为true
等。 - 跨域问题:由于
Cookie
只能在同域名下共享,因此跨域访问时无法访问到对应的Cookie
信息。这时,可能需要采用一些其他的跨域解决方案,如JSONP、CORS
等。 - 扩展性问题:由于
Session
信息存储在服务器端,当系统扩展到多台服务器时,需要采用一些集中式的Session
管理方案,否则会出现Session
不一致或者丢失等问题。 - 性能问题:由于
Session
信息存储在服务器端,因此每次请求都需要从服务器读取Session
信息,这可能会导致性能问题。为了解决这个问题,可以采用一些缓存方案来提高访问速度。 - 一些移动设备和浏览器可能会禁用
Cookie
和Session
机制,这会导致无法正常登录。
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 单点登录的缺点
- 单点故障:由于单点登录系统需要负责所有应用程序的身份认证和授权,一旦发生故障或被攻击,则会影响所有应用程序的正常运行。
- 安全问题:由于单点登录系统涉及到多个应用程序的身份认证和授权,因此安全性问题尤为重要。如果认证系统遭受攻击,则可能导致多个应用程序的信息泄露或数据损坏。
- 中心化依赖:由于单点登录系统是集中式的,因此对于大规模分布式系统而言,如果需要多台服务器之间共享认证信息,则需要采用一些集中式的认证管理方案。
- 可扩展性问题:由于单点登录系统需要处理多个应用程序之间的身份认证和授权,因此在实现时需要考虑其可扩展性问题。例如,在增加新的应用程序时,单点登录系统需要进行相关配置和调整,以保证其正常运行。
- 维护成本:由于单点登录系统需要负责多个应用程序的身份认证和授权,因此其维护和管理成本相对较高。例如,在增加新的应用程序或更改现有应用程序时,需要对单点登录系统进行相应的调整和测试,以确保其正常运行。
OAuth2 第三方登录
OAuth
是一种常用的开放标准协议,用于在不同应用之间安全共享用户资源(如个人信息、照片、视频等)。
目前已经发展到OAuth2.0
版本,相较于1.0
版本更加关注客户端开发者简易性,而且为桌面应用、web应用、手机设备提供专门认证流程。
而第三方登录则是OAuth
协议中的一种应用场景。具体来说,第三方登录是指用户选择使用第三方平台的身份认证服务来登录某个应用程序。
OAuth2.0
标准定义四种角色:
- 认证服务器(
Authorization Server
):认证服务器是授权过程的“受信任的第三方”,负责颁发访问令牌(Access Token
),用于访问资源服务器。 - 资源服务器(
Resource Server
):资源服务器是托管受保护资源的服务器,例如照片、视频、个人资料等。 - 客户端(
Client
):客户端是请求访问受保护资源的应用程序。它可以是Web应用程序,移动应用程序,桌面应用程序等。 - 资源所有者(
Resource Owner
):资源所有者是拥有受保护资源的用户。他们授权客户端访问其资源。
其实 OAuth2.0
标准定义四种授权模式:
- 授权码模式(authorization code)
- 隐式模式(implicit)
- 密码模式(password)
- 客户端模式(client credentials)
四种授权模式中最常用的是授权码模式。
授权码模式是指第三方应用先申请一个授权码,然后再用该码获取令牌。这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。
基本流程
授权码方式授权大体上分为四步:
- 第三方应用引导用户访问授权服务器,尝试获取用户授权,用户选择是否授权
- 授权服务器获取到用户授权后,给应用服务器返回授权码
- 应用服务器携带授权码向授权服务器请求令牌,授权服务器对授权码及客户端秘钥认证成功后发放令牌
- 应用服务器携带令牌向授权服务器请求用户信息,授权服务器对令牌进行认证后返回所需信息
以微信登录为例,当用户在某个网站或应用上选择使用微信登录时,该网站会向微信发送一个授权请求,微信会提示用户确认授权,并返回一个令牌(access token
)给该网站,该网站通过验证令牌的有效性后,即可实现用户的自动登录和获取用户的相关信息。
OAuth2优势
相比于传统的用户名密码登录方式,第三方登录具有以下优势:
- 便捷性:用户可以直接使用其已有的社交账号登录,无需再次注册或填写信息,提高了用户体验。
- 安全性:第三方平台通常会对用户的信息进行加密存储和传输,在一定程度上提高了用户数据的安全性和保密性。
- 防止账号被盗:由于用户不需要在每个应用中输入账号和密码,因此也降低了账号被盗的风险。
需要注意的是,虽然第三方登录可以提高用户体验和安全性,但也存在一些潜在的安全风险,例如用户授权过多、第三方平台信息泄漏等问题。
因此,在实际的开发和应用中,需要合理选择第三方平台、进行授权管理、保护用户隐私等措施,以确保用户数据的安全性和可靠性。
扫码登录
扫码登录是一种快捷方便的登录方式,用户只需要通过扫描二维码即可完成登录操作,无需输入用户名和密码等信息。在网页、APP 等应用中广泛应用,可以提高用户使用体验和安全性。
基本流程
以扫码登录某个网站为例:
- 打开登录页面,展示一个二维码,同时轮询二维码状态(web)
- 打开APP扫描该二维码后,APP显示确认、取消按钮(app)
- 登录页面展示被扫描的用户头像等信息(web)
- 用户在APP上点击确认登录(app)
- 登录页面从轮询二维码状态得知用户已确认登录,并获取到登录凭证(web)
- 页面登录成功,并进入主应用程序页面(web)
真实案例
以“前端面试题宝典”的 PC 端登录为例,就是使用了微信扫码能力和小程序的授权功能。
首先,PC 端在进行登录操作时,会从后端请求一个临时的小程序二维码进行展示,二维码中会包含一个 id 参数,并根据该 id 轮询扫码状态。
引导用户使用微信扫码后,会在微信中打开“前端面试题宝典”小程序,跳转到小程序中一个专门的授权登录页面,并在该页面会请求用户的部分数据。
用户确定授权后,会将授权数据同步给后端。
PC 端在下次轮询时拿到授权成功的状态及用户头像等数据,完成登录操作。
扫码登录优势
扫码登录有以下优势:
- 方便快捷:扫一下二维码即可完成登录,无需输入账号密码等信息,操作简单方便。
- 安全性高:相比于传统的用户名和密码方式,扫码登录更加安全,因为扫描过程中不会暴露敏感信息,如密码等。
- 体验好:扫码登录无需手动输入任何信息,对于移动设备尤其友好,用户体验更好。
当然,由于扫码登录需要使用到第三方平台,例如微信、支付宝等,可能会涉及到第三方的隐私问题和数据共享问题。
一键登录
一键登录,也叫“本机号码一键免密登录”,是指用户在移动端应用或网站中,通过验证手机号快速完成登录的方式。
这是一种更为“懒人”的验证方式,既不需要用户输入账号密码,也不需要输入手机号来获取短信验证码,接受协议后,直接由运营商帮助APP取号验证,用户可以点击一键登录。
相比于传统的账号密码登录方式,一键登录更加方便快捷,并且可以免除密码管理和找回密码等问题。
一键登录的原理
要使用一键登录,需要接入运营商的 SDK,三大运营商使用了同一套授权流程:
主要步骤如下:
- SDK 初始化
调用 SDK
的初始化方法,传入项目在平台上的 AppKey
和 AppSecret
。
- 唤起授权页
调用 SDK 唤起授权接口。SDK 会先向运营商发起获取手机号掩码的请求,请求成功后跳转到授权页。授权页会显示手机号掩码以及运营商协议给用户确认。
- 同意授权并登录
用户同意相关协议,点击授权页面的登录按钮,SDK
会请求本次取号的 token
,请求成功后将 token
返回给客户端。
- 取号
将获取到的 token 发送到我们自己的服务器,由服务器携带 token
调用运营商一键登录的接口,调用成功就返回手机号码了。服务器用手机号进行登录或注册操作,返回操作结果给客户端,完成一键登录。
在没有插电话卡,或者关闭移动蜂窝网络的情况下,是无法完成认证的。所以就算接入了一键登录,我们也要兼容传统的登录方式,允许用户在认证失败的情况下,手动输入手机号登录。
小结
Cookie + Session
、Token
、SSO单点登录
是常见的身份认证和授权方案,它们各有特点:
-
Cookie + Session:该方案通常用于同一域名下的应用程序之间的身份认证。它通过浏览器的 Cookie 和服务器端的 Session 机制来共享用户信息和状态,但需要注意的是,由于 Cookie 和 Session 都是存储在客户端或服务端的,因此可能存在被盗用或篡改的风险。
-
Token:该方案通常用于跨域身份认证和授权。它通过生成加密签名的 Token 来代表用户身份和权限,并将 Token 传递给其他应用程序进行验证。相比于 Cookie + Session 方案,Token 方案更加安全可靠,但也需要注意 Token 的有效性和安全性等问题。
-
SSO 单点登录:该方案通常用于多个应用程序之间的身份认证和授权。它通过引入认证中心来统一管理用户身份和权限,从而避免了重复登录和重复授权的问题。相比于 Cookie + Session 和 Token 方案,SSO 单点登录方案更加便捷和高效,但同时也存在单点故障和安全问题等风险。
需要注意的是,根据具体业务需求和安全要求,可以选择不同的身份认证和授权方案,并在实现时结合一些安全措施来保障用户信息的安全性。同时,在使用 Token 和 SSO 单点登录方案时,还需要对 Token 和认证中心进行管理和维护,以保证其正常运行和可靠性。