点击蓝字
关注我们
始于理论,源于实践,终于实战
老付话安全,每天一点点
激情永无限,进步看得见
严正声明
本号所写文章方法和工具只用于学习和交流,严禁使用文章所述内容中的方法未经许可的情况下对生产系统进行方法验证实施,发生一切问题由相关个人承担法律责任,其与本号无关。
特此声明!!!
OAuth是什么
OAuth是一套身份认证授权协议,用于安全地访问用户在不同应用程序系统上存储的信息,无需共享密码。
以往我们登录应用程序需要进行注册,通过用户名密码等方式进行登录应用程序。这样以来,用户就行需要维护和记忆许多用户名密码,是不是在日常冲浪时也有记混淆密码的时候,也有的所有的登录应用程序密码全部使用相同的用户名密码。安全性不高的应用程序就有可能泄露你的用户名密码,如果网银也使用了相同的用户名密码就有可能造成财产损失,当然网银不光是用户名密码还有更多安全措施。
用户需要记录用户名密码,其实后端服务器也要存在相应的用户名密码。当用户登录时后端服务器会检查这些信息是否与存储的有效用户凭据相匹配。如果匹配成功,服务器会返回一个认证令牌(如JWT、Session ID等)给前端,这个令牌在后续的请求中会被用来验证用户的身份和权限。返回令牌是因为HTTP协议是无状态,服务器无法识别连续的请求是否来自同一用户,于是为了缓解服务器的压力,使用Session认证机制。
Session认证机制当服务器将Session ID存储在响应的Cookie中返回给客户端。服务器验证用户名和密码,如果验证通过,则创建或更新一个会话(Session),并将会话标识(Session ID)存储在服务器的会话表中。客户端接收到响应后,将Session ID存储在Cookie中。在后续的请求中,客户端会自动将Cookie中的Session ID发送给服务器。服务器通过Session ID查找对应的会话信息,从而验证用户的登录状态。这样就不用每次请求都去验证用户名密码,提高了效率。(注意:Session 是存储在服务器端的,Cookie 是存储在客户端的。Cookie 会记录 SessionID 属于哪个域名)。用户登录成功将其信息存入session中,用户每次请求都会将携带session id的cookie一起发送器服务端,进行校验,随着Web、应用程序、以及移动端的崛起,这种验证方式弊端逐渐显现,尤其是在可扩展性方面。
那有没有其他方式可以解决服务器少存储用户登录信息的,而且扩展性好的认证?那就试试令牌认证吧。
什么是 Token(令牌)
Token 是一种用于验证用户身份的凭证。例如,JWT(JSON Web Token)是一种常见的Token格式,用于在客户端和服务器之间传递用户信息。是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。token就像是保险箱钥匙,有了这把钥匙,就能够访问到保险箱中的东西。
token 的身份验证流程:
来源网络
-
客户端使用用户名跟密码请求登录
-
服务端收到请求,去验证用户名与密码
-
验证成功后,服务端会签发一个 token 并把这个 token 发送给客户端
-
客户端收到 token 以后,会把它存储起来,比如放在 cookie 里或者 localStorage 里
-
客户端每次向服务端请求资源的时候需要带着服务端签发的 token
-
服务端收到请求,然后去验证客户端请求里面带着的 token ,如果验证成功,就向客户端返回请求的数据
Token 存储在哪里?
-
存到数据库中,每次客户端请求的时候取出来验证(服务端有状态)
-
存到 redis (键值对数据库服务器)中,设置过期时间,每次客户端请求的时候取出来验证(服务端有状态)
-
不存,每次客户端请求的时候根据之前的生成方法再生成一次来验证(JWT,服务端无状态)
引入Token验证机制后,请求只发送token而不再是发送cookie能有效够防止CSRF,即使在客户端使用cookie存储token,但cookie也只有存储功能,而不再具备验证功能,因此安全性得到了极大的提高。只要token设计的足够复杂,除非用户泄露,否则几乎没有被破解的可能,加上token是有时效的,在有限的时间加上有限的算力,更是无懈可击,这也类似于加密资产比如比特币钱包对应的私钥,安全性极高。(现在许多API接口验证访问几乎都采用API token的方式)。
在token认证中一种特殊token,JSON Web Token(JWT),它是跨域认证解决方案。
JWT特殊在哪里呢?
JWT由三部分组成用点号(.)分隔
如:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjc4MTc3MjAwLCJleHAiOjE2NzgxODA4MDB9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
-
Header:包含Token的类型(如JWT)和签名算法(如HMAC SHA256)。
如:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
它编码前是这样的:
{
"alg": "HS256",
"typ": "JWT"
}
-
Payload:包含实际的数据(如用户ID、角色、过期时间等),称为“声明”(Claims)。
如:
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjc4MTc3MjAwLCJleHAiOjE2NzgxODA4MDB9
它编码前是这样的:
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1678177200,
"exp": 1678180800
}
-
Signature:对Header和Payload的签名,用于验证Token的完整性和真实性。
如:
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5
它编码前是这样的:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload),secret )
普通Token通常没有这种标准化的结构,可能只是一个简单的字符串或加密后的数据。
JWT 是自包含的(内部包含了一些会话信息),减少了需要查询数据库的需要。
JWT 并不使用 Cookie 的,所以使用任何域名访问你的 API 服务而不需要担心跨域问题。
用户的状态不再存储在服务端的内存中,所以是一种无状态的认证机制。
token认证方式已经比较好了,为啥还需要oAuth认证?它们有什么区别?
OAuth(开放授权)是一个开放标准,用于授权一个应用程序或服务访问用户在另一个应用程序中的资源,而无需提供用户名和密码。
JWT(Json Web Token)是一种用于在网络应用环境间传递声明的基于JSON的开放标准。主要用于身份验证和授权,通过在客户端和服务器之间传递令牌来实现无状态的认证机制。
OAuth主要用于第三方应用访问用户资源,而JWT主要用于服务间的身份验证和授权。OAuth需要用户明确授权,适用于需要用户授权的场景;JWT则更适合无状态的API调用,减少服务器的存储和计算负担。
通俗来讲:想象你住在一个高档小区,物业给你一张门禁卡。朋友来你家时,你不需要把家门钥匙给他,而是让物业给他一张临时通行卡,且这张卡只能刷电梯到你的楼层,不能进其他住户家——这就是OAuth的核心逻辑。
第三方登录场景下,用户不用再注册新账号,一键授权即可登录,避免记住多个密码的麻烦。减少注册步骤,一键登录,用户流失率降低。
传统方式中,用户把密码交给第三方,风险极高;用户只授权“临时通行证”,不暴露密码,权限可随时收回。这就是oAtuh认证的魅力。
OAuth认证详解
Oauth认证参与方的角色
我们通过一张图来了解各方都是谁
-
资源拥有者:用户,
-
用户代理:浏览器
-
客户端应用程序:这里我们以知乎为例,知乎上可以通过微信进行登录。
-
授权服务者:这里是微信登录授权
OAuth认证运行的基本流程
-
(A)用户打开客户端(知乎)以后,客户端(知乎)要求用户给予授权。
-
(B)用户同意给予客户端授权。
-
(C)客户端使用上一步获得的授权,向认证服务器(微信认证服务器)申请令牌。
-
(D)(微信)认证服务器对客户端进行认证以后,确认无误,同意发放令牌。
-
(E)客户端(知乎)使用令牌,向资源服务器(存放用户邮箱、用户名、头像等信息的微信服务器)申请获取资源。
-
(F)资源服务器确认令牌无误,同意向客户端开放资源。
OAuth是一类基于回调的授权协议,所以要使用OAuth
有个前置条件,应用程序(知乎)要使用第三方认证(微信),需要向认证服务提供商(微信)申请获取授权回调URL,因为认证服务商需要把授权码或令牌返回给原始请求的应用程序(知乎),而不是其他应用程序,这样防止了一些安全隐患。以下是需要申请的内容:
申请时,应用程序需要提供,应用程序的名称、应用程序的URL,认证服务器把授权码或者令牌返回给谁(即授权回调URL,它可能是这样的:https://www.zhihu.com/oauth/callback/wechat?action=login&from=;后边的部分需要开发人员编写自己的接收方式,以备自己能够正常接收授权码或者令牌,这防止中间人截获授权码或令牌)。同时认证方会给应用程序颁发客户端标识 client_id(唯一对应是知乎,而不是其他的客户端)、客户端密钥 client secret(获取token时加密使用)。完成之后,就可以进行认证了。详细的认证过程,内容有点多,我们下期再聊。力争能够让各位同仁能够理解透彻。
END
老付
欢迎扫码
关注我们
网络安全
原文始发于微信公众号(老付话安全):一次性讲清楚OAuth2.0认证(一)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论