授权方案(php实现)
授权方案(php实现)
以下方案为用户登录授权参考
1. 采用数据库授权
本方法仅仅只在laravel实验过
思路
首先在用户表添加一列为token列,然后在登录校验成功之后,生成token,将其添加至数据库,并在登录成功之后返回token和用户id,在用户需要登出时,清空token列数据,在这个的基础上增加一个定时器,检查用户表的更新时间,当用户表的更新时间超过规定时间时,自动清空token列内容。
特征
- 缺陷明显: 首先此方法无法使用在大量用户场景,因这样会产生大量的sql操作,极大降低服务器性能
- 存在错误: 当用户表修改频繁时,会直接延长有效时间 总结这个方法既繁琐又低效。
2. 采用redis实现授权(基本)
思路
首先生成完token之后使用redis的键值模式存储token,键名建议写成如下格式:
[project_name]:user:[user_id]
然后使用对应的redis工具类存储,当他需要登出时结合用户id和token做一次校验,然后使用对应的redis删除即可,redis是有对应的方法设置过期时间。redis工具类实现见[[redis工具封装(基于laravel)]]
特征
- 省事
- 明码传输用户信息(?这个的描述有点问题) 这个方法只适合单纯的用户登录状态校验,并不对用户信息做存储,所以获取用户信息,只能通过再请求而无法通过其他方法获取。
- 可存储的信息较短 因为它在存储的过程中只能存储token所以要查看用户信息时是需要查询数据库。
- 若出现集群,需要将所有的服务端连入同一个redis
补充: 这个方法其实就是是Session ID,目标就是利用这个ID进行业务交互。
3.基于JWT形式的授权
JWT概念
JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。
{
"name": "张三",
"role": "管理员",
"expiraTime": "2022-11-9 00:00:00"
}
以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名。 服务器就不保存任何 session 数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。
整体结构:
header
标头通常由两部分组成:令牌的类型(JWT)和正在使用的签名算法,例如 HMAC SHA256 或 RSA。 例如:
{
"alg": "HS256",
"typ": "JWT"
}
然后通过Base64URL编码,得出第一部分
payload
令牌的第二部分是payload,其中包含claims。claims是关于实体(通常是用户)和其他数据的语句。claims分为三种类型:注册claims、公共claims和私人claims。
- 已注册
claims:这些是一组预定义的claims,这些claims不是强制性的,但建议提供一组有用的、可互操作的claims。其中一些是:iss(发行人)、exp(到期时间)、sub(主题)、aud(受众)等。 - 公共
claims:这些claims可以由使用 JWT 的人随意定义。但为了避免冲突,应在 IANA JSON Web 令牌注册表中定义它们,或将其定义为包含防冲突命名空间的 URI。 - 专用
claims:这些是自定义claims,用于在同意使用它们的各方之间共享信息,既不是注册claims,也不是公开claims。 一般是传输用户非敏感信息所使用的 例:
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
然后通过Base64URL编码,得出第二部分
signature
要创建signature部分,您必须获取编码的标头、编码的payload、secret、header中指定的算法,并对其进行签名。 例如,如果要使用 HMAC SHA256 算法,则将按以下方式创建签名:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
这里的secret是你自己生成出来的,这个整体用于验证消息在此过程中没有更改,对于使用私钥签名的令牌,它还可以验证 JWT 的发送者是否是他本人。
特征
- 不安全 因为信息是直接储存在
payload里面的,而且还是无状态的,所以只能等jwt自己过期了才可以删除,一旦泄露就可以使用其获取用户信息 - 可扩展 因为是直接携带JSON返回,所以可以直接拓展返回信息
- 降低数据库的使用 因为其本身的特性,所以可以交换信息,降低服务器查询数据库的次数 具体实现见:JWT实现 但是这个方案较老,不适宜再使用
4. OAuth2登录认证
OAuth概念
OAuth 2.0是一个业界标准的授权协议,其定义了四种可以适用于各种应用场景的授权交互模式:授权码模式、应用授信模式、用户授信模式、简化模式。其中,授权码模式被广泛应用于第三方互联网开放平台,通过第三方登录是其最常见应用场景之一,比如使用微信、QQ和淘宝账号进行登录。 通俗点说就是当有第三方应用需要授权你服务器的用户信息时,可以通过这个方式进行授权。 参与该模式的有四个角色:
- 第三方应用
- 授权服务器
- 资源服务器
- 用户
流程:
首先第三方应用请求认证服务器获取token,然后认证服务器询问用户是否同意授权,当用户同意授权时,认证服务器将token发送至第三方应用,然后第三方应用通过token请求资源服务器。 在这里,第三方应用可以转换成为客户端,然后授权和资源服务器为同一服务端,授权服务器负责token的续期以及请求客户端的管理。 如果这是第一次授权则请求对应的客户端密钥进行存储,以证明用户已授权过,下一次授权就可以使用客户端密钥进行授权。
特征:
- 因为token本身也是由JWT生成的,所以在token本身继承了所有JWT里的token的特点。
- 相较于JWT来说要安全些,因为做了两次授权
- 用户能够选择哪些资源可以被访问,而不必共享他们的密码。
- OAuth2相较于JWT来说要复杂些 具体实现:laravel passport
dawd