大部分项目都离不开登录阶段,但是登陆的实现多种多样。
常见的登录方式有单点登录,多点登录。登录的时候要考虑的东西也非常多,例如异地登录保护等等,这些所有的一切都是为了更大程度上的保护用户的信息安全。
接下里将详细介绍三种登录技术。
第一种session
Session登录是一种在Web应用程序中用于跟踪用户状态的机制。当用户登录到一个应用程序时,服务器会为该用户创建一个唯一的会话ID,并将该ID存储在一个称为Session的服务器端存储中。随后,每当用户与应用程序进行交互时,会发送该会话ID给服务器,服务器利用该ID来识别用户并提供相应的数据。
通过Session登录,应用程序可以在用户多次请求之间保持用户的登录状态。这对于需要用户身份验证或需要跟踪用户操作的应用程序非常有用。服务器可以将用户的登录信息存储在Session中,以便在用户访问其他页面时进行验证,或者在不同的用户请求之间保持用户的登录状态。
通常,Session登录的过程是用户在登录页面上输入用户名和密码进行认证,服务器验证用户的身份信息后,在服务器端创建一个会话并为该会话分配一个唯一的会话ID。该会话ID会被存储在用户的浏览器中,通常以cookie的形式存储。用户在后续的请求中会携带该会话ID,服务器通过该ID来查找并关联用户的会话信息。
使用Session登录可以确保用户只需一次登录,并在整个会话期间保持登录状态,使得用户可以访问需要身份验证的页面或功能。同时,应用程序也可以在用户操作期间持续存储和处理与用户相关的数据。
但是session登录如果运用在计算机集群上就会出现信息不一致问题,我们要保证会话的同步,这需要一定的服务器通信代价。
第二种token+redis
使用Token和Redis进行登录是一种常见的实现方式,它可以提供更高的性能和扩展性。具体实现方式如下:
-
用户登录:用户提供用户名和密码进行登录验证。验证成功后,服务器生成一个唯一的Token,并将Token作为键和用户身份信息作为值存储在Redis中。同时,将Token返回给客户端。
-
客户端请求:客户端在每次请求需要身份验证的接口时,将Token放在请求的头部或其他指定位置上。
-
服务器验证:服务器在接收到请求时,从请求中获取Token。服务器通过查询Redis,检查该Token是否有效并获取相应的用户身份信息。
-
响应和更新Token:如果Token有效,服务器继续处理请求并发送响应给客户端。在响应返回给客户端之前,可以选择更新Token,以避免过期。更新Token的方式可以是生成一个新的Token,将其作为新键,将旧Token对应的用户信息作为值存储在Redis中,然后将新Token返回给客户端。
-
登出和过期:当用户登出或Token过期时,服务器从Redis中删除对应的Token和用户信息。
使用Token和Redis进行登录的好处是,服务器无需保持用户的状态信息,将用户信息存储在Redis中可以有效减轻服务器的负担,并支持分布式应用程序的扩展。另外,Token具有一定的安全性,可以设置过期时间和密钥等措施来增强安全性。
但是token一般都是随机生成的字符串,存在数据库会造成资源消耗。
第三种jwt
相对复杂
JWT(JSON Web Token)是一种用于认证和授权的开放标准,通常用于实现无状态的身份验证机制。JWT使用JSON对象来传输被称为Claim(声明)的用户信息,这些信息可以被加密和签名以确保其完整性和安全性。
JWT登录的过程如下:
-
用户登录:用户提供用户名和密码进行身份验证。
-
服务器生成Token:服务器验证用户的身份信息后,生成一个包含用户信息(如用户ID、角色等)的JWT Token。Token由三个部分组成:头部、载荷和签名。
-
返回Token给客户端:服务器将生成的Token作为响应返回给客户端。
-
客户端存储Token:客户端将接收到的Token保存在本地,通常存储在Cookie或本地存储中。
-
客户端请求:在每次需要进行身份验证的请求中,客户端将Token放在请求的头部(通常是Authorization头部)或其他指定位置上。
-
服务器验证Token:服务器收到请求后,从请求中获取Token,并进行签名和解密操作以验证Token的完整性和有效性。服务器还可以从Token中提取出用户信息,用于识别和授权用户。
-
响应和更新Token:如果Token验证成功,服务器继续处理请求,并根据需要发送响应给客户端。在每次响应返回给客户端之前,服务器可以选择更新Token,以避免过期。更新Token的方式可以是生成一个新的Token,替换旧的Token。
-
登出和过期:如果用户登出或Token过期,客户端可以删除存储的Token,服务器不再接受该Token进行身份验证。
JWT登录的优势在于,可以实现无状态认证,避免服务器存储会话信息,减轻服务器的负担,并将用户信息放在Token中,减少数据库查询。同时,JWT还允许服务器对Token进行签名和加密,确保Token的安全性。然而,需要注意的是,JWT Token一旦签发,其内容无法更改,除非新签发一个Token。因此,在设计和使用过程中需要考虑Token的过期时间和刷新机制。
JWT消息构成:
JWT(JSON Web Token)由三个部分构成:头部(header)、载荷(payload)和签名(signature)。
- 头部(header):头部由两部分组成,第一部分是令牌的类型和签名算法,通常是JWT。第二部分是一个JSON对象,描述了使用的签名算法等元数据信息。这部分通常使用Base64编码,并将其放在JWT的第一个点(.)之后。
示例头部:
{
"alg": "HS256",
"typ": "JWT"
}
- 载荷(payload):载荷是JWT的实际数据部分,用于携带有关用户身份和其他相关声明的信息。它包含一组称为声明(claims)的JSON对象,声明可以是标准声明(例如,用户ID、过期时间等)或自定义声明。
常见的标准声明包括:
- “iss”(Issuer):JWT的签发者
- “sub”(Subject):JWT所面向的用户
- “exp”(Expiration Time):JWT的过期时间
- “iat”(Issued At):JWT的签发时间
示例载荷:
{
"iss": "example.com",
"sub": "user123",
"exp": 1632124800
}
- 签名(signature):签名是由头部和载荷组成的字符串通过密钥进行加密后得到的字符串。签名的目的是确保JWT的完整性和真实性,防止篡改。
签名的过程通常如下:
- 使用Base64编码的头部和载荷,将它们通过英文句点(.)连接起来形成一个字符串。
- 使用指定的算法(如HMAC SHA256)和密钥对上一步形成的字符串进行签名。
- 将签名结果进行Base64编码,得到最终的签名字符串。
最终的JWT格式如下:
<header>.<payload>.<signature>
每个部分都通过英文句点(.)分隔。
注意,JWT的签名部分需要使用服务器端的密钥进行加密和解密,以确保只有授权的服务器才能正确验证JWT的完整性。
通过合法的JWT,服务器可以验证Token的完整性、读取载荷中的声明信息,并采取相应的授权或认证操作。