一、OAuth2.0 基本概念
OAuth2.0 是一种开放标准授权协议,可让第三方应用在用户许可的前提下,获得用户在某平台的资源(比如微博、微信、GitHub、企业微信等)。最常用于用户"用XX账号登录"第三方网站,以及内部微服务统一用户授权和认证。
- OAuth2.0 关注授权(Authorization): 即,谁有权访问哪些资源。
- OpenID Connect (OIDC) 关注身份认证(Authentication): 是OAuth2之上的身份认证扩展标准。
二、核心角色
- 资源拥有者(Resource Owner)
- 通常是用户本人。
- 客户端(Client)
- 需要访问资源的第三方应用,比如“用微信登录”的第三方App。
- 授权服务器(Authorization Server)
- 负责用户登录、授权、颁发token的服务器。
- 资源服务器(Resource Server)
- 用户真实资源的服务器,用于校验token并提供接口(比如微博API)。
三、标准授权流程(Authorization Code 授权码模式)
这是 OAuth2最常见、最安全的一种授权流程,充分保护用户密码和隐私。
步骤说明
-
客户端请求授权
用户在第三方应用上点击“用XX账号登录”,被重定向到授权服务器的授权页面(比如微信的扫码登录页)。 -
用户登录并授权
用户输入账号密码,并确认“允许xxx应用访问我的信息”。 -
授权服务器返回授权码(auth code)
授权服务器重定向回客户端预留的回调地址,带上短时有效的授权码(code)。 -
客户端凭授权码后台换取access_token
客户端服务器拿着code、client_id、client_secret等信息,请求授权服务器,获得access_token和(有时还有)refresh_token。 -
客户端用access_token访问资源服务器API
前端或后端用access_token访问资源服务器,获得用户基本信息,如昵称、头像、手机号等。
时序图
[用户] ---点击登录---> [客户端(第三方App)]
|
|--redirect---> [授权服务器]
|
<--授权页面(输入密码/同意授权)-->
|
<--带code回调--> [客户端(后台服务器)]
|
---用code换token---> [授权服务器]
|
<--access_token/refresh_token--
|
---用access_token请求API---> [资源服务器]
|
<--用户数据---
四、几种常见授权流程模式
- 授权码模式(最常用,见上)
- 简化模式(Implicit):主要用于前端单页应用,token直接写在URL,但安全性较弱。
- 客户端凭证模式(Client Credentials):服务—服务场景,服务用自己的凭证请求token,无须用户授权。
- 密码模式(Resource Owner Password Credentials):应用直接收集用户密码,安全性较差,仅用于可信应用。
- JWT Bearer模式:服务间用JWT做认证。
五、token类型说明
-
access_token
用于访问资源服务器API。通常有有效期(如2小时),过期后需重新授权或刷新。 -
refresh_token
用于在access_token过期后,免用户再次授权,后台直接获取新的access_token。有效期较长(如30天)。 -
id_token
OIDC协议才有,表示用户身份信息(JWT格式),适合SSO场景。
六、OAuth2关键参数和接口举例
1. 授权请求(redirect到授权服务器)
GET https://oauth.server.com/authorize?
response_type=code
&client_id=你的应用id
&redirect_uri=回调地址
&scope=要访问的权限
&state=随机字符串防止CSRF
2. 获取token
POST https://oauth.server.com/token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=授权码
&client_id=你的应用id
&client_secret=你的秘钥
&redirect_uri=回调地址
3. 访问用户信息
GET https://oauth.server.com/userinfo
Authorization: Bearer access_token
七、安全注意事项
- 使用HTTPS,防止token泄露。
- state参数防CSRF攻击,state要随机生成并校验回调的一致性。
- access_token要带有效期、权限scope做最小授权原则。
- refresh_token妥善保存只在服务端使用。
- 回调地址(redirect_uri)需提前注册、校验,防止盗用。
- token用JWT或其他方式签名,校验合法性和防篡改。
八、实际应用场景
- “第三方快速登录”页面(微信、钉钉、支付宝等)
- 微服务、BFF网关间资源访问控制
- 内部企业应用单点登录
- API 接口授权管理体系
九、开源解决方案与框架推荐
- Keycloak(Java、支持OAuth2/OIDC/SAML等标准,适合微服务接入SSO与统一授权)
- Spring Security OAuth(Java生态下微服务授权首选)
- OAuthlib/Flask-OAuthlib(Python应用:快速集成OAuth2流程)
- Authing、Okta、OneLogin(SaaS平台,免运维开箱即用)
十、常见问题简答
-
如何实现多个应用的单点登录?
用统一的OAuth2认证中心,所有业务应用对接登录流程与token校验即可。 -
怎样实现安全退出?
让所有token失效(如在SSO中心统一删除token),或通知业务系统清除本地Session。 -
token存储在哪里最安全?
Web端建议存为HttpOnly/Secure Cookie,APP端建议安全区或加密存储。
十一、简单伪代码示例(Python Flask)
# 假设用 Flask-OAuthlib
@app.route("/login")
def login():
oauth = OAuth2Session(client_id, redirect_uri=redirect_uri)
auth_url, state = oauth.authorization_url(auth_server)
return redirect(auth_url)
@app.route("/callback")
def callback():
code = request.args.get('code')
token = oauth.fetch_token(token_url, code=code, client_secret=client_secret)
userinfo = oauth.get(userinfo_api, token=token)
return "登录成功,用户头像:%s" % userinfo["avatar"]

4553

被折叠的 条评论
为什么被折叠?



