OAuth 2.0第三方授权登录

认证和授权的概念和区别

  • 认证 (Authentication[ɔːˌθentɪˈkeɪʃn] ): 你是谁。
  • 授权 (Authorization[ˌɔːθəraɪˈzeɪʃ(ə)n]): 你有权限干什么。

概念:

  • Authentication(认证) 是验证您的身份的凭据(例如用户名/用户 ID 和密码),通过这个凭据,系统得以知道你就是你,也就是说系统存在你这个用户。所以,Authentication 被称为身份/用户验证。
  • Authorization(授权) 发生在 Authentication(认证) 之后。授权嘛,光看意思大家应该就明白,它主要掌管我们访问系统的权限。比如有些特定资源只能具有特定权限的人才能访问比如 admin,有些对系统资源操作比如删除、添加、更新只能特定人才具有。

认证:

认证登录

认证登录

授权:

没有权限

没有权限

这两个一般在我们的系统中被结合在一起使用,目的就是为了保护我们系统的安全性。

OAuth协议

概念

第三方授权登录一般是通过 OAuth 来做的,这是一个行业标准授权协议,主要用来授权第三方应用获取有限的权限以访问受保护的资源(比如用户的信息)。也就是说, OAuth 实际解决的是授权问题而不是认证问题 。可以理解为授权是第三方平台授权你访问它的用户信息,认证是你在自己的平台依据拿到的用户信息进行登录。

基本流程

OAuth 2.0 第三方授权登录的基本流程如下:

  1. 客户端向资源拥有者也就是用户发送授权申请。
  2. 用户同意给予客户端授权。
  3. 客户端使用上一步获得的授权,向认证服务器申请 Access Token(访问令牌)。
  4. 认证服务器对客户端进行认证以后,确认无误,同意发放 Access Token。
  5. 客户端使用 Access Token,向资源服务器申请获取资源。
  6. 资源服务器确认 Access Token 无误,同意向客户端开放资源。
 OAuth 2.0授权模式:
  1. 授权码模式是 OAuth 2.0 中最常用的模式之一,也是最安全的一种模式。在这种模式下,客户端先申请一个 Authorization Code(授权码),然后再用该码获取 Access Token(访问令牌)。
  2. 隐藏/简化模式:隐藏/简化模式是一种简化的授权码模式,这种方式没有申请 Authorization Code 这个中间步骤,直接将 Access Token 传递给客户端,所以称为隐藏/简化模式。
  3. 密码模式:密码模式是一种在用户信任客户端的情况下使用的模式,因为客户端需要直接从用户那里获取用户名和密码,并将其作为 Client Credentials(客户端凭证)发送到认证服务器来换取访问令牌。但是,这可能会使用户的密码泄露,因此应该谨慎使用。
  4. 客户端凭证模式:客户端凭证模式是一种不基于用户的认证模式,它允许客户端直接使用 Client Credentials 向认证服务器请求令牌。
授权码模式的授权验证流程

整个流程主要分为以下六步:

1、客户端请求授权

用户访问客户端(第三方应用),客户端引导(重定向)用户的代理(浏览器)去到认证服务器的授权页面,这个时候客户端会在 URI 上附上 Client ID(客户端 ID,用于唯一标识)、Rediection URI(重定向 URI)和 Response Type(响应类型)、Scope(授权作用范围)等信息。

2、认证服务器要求用户授权

认证服务器验证客户端身份和访问权限,并要求用户提供认证信息进行身份验证,确定用户是否授权请求。



3、用户同意授权,认证服务器返回 Authorization Code

用户同意授权后,认证服务器将 Authorization Code(授权码)传递给客户端,客户端收到 Authorization Code 后可以使用它来请求 Access Token。

4、客户端使用授权码申请访问令牌

客户端使用 Authorization Code 向认证服务器申请 Access Token,这个时候客户端会在 URI 上附上 Client ID、Client Secret Key (客户端秘钥)Authorization Code 和 Rediection URI 等信息。

5、认证服务器颁发 Access Token

认证服务器认证客户端,检验 Authorization Code 以及 Rediection URI,检验成功后发放 Access Token 以及 Refresh Token(刷新令牌,可选)。

6、访问资源服务器对应的资源

客户端使用访问令牌向资源服务器请求被保护的资源。

什么情况下 Access Token 应该失效?

除了过期之外,下面这三种情况 Access Token 也应该失效:

  1. 用户修改帐户密码。
  2. 用户冻结或者注销帐号。
  3. 用户取消对改第三方应用授权。


Authorization Code 一般有效期多久?

Authorization Code 有效期应该设置得尽可能短,以提高安全性。一般来说,推荐将 Authorization Code 的有效期设置为 5~20 分钟。并且,Authorization Code 通常只能使用一次,不可重复使用。

除了 Access Token 之外,为什么还有一个 Refresh Token 呢?

Access Token可以采用两层过滤器进行刷新。

这是因为 Access Token 只是向资源服务器申请获取资源的凭证,其有效期一般较短,通常在 2~3 个小时。当 Access Token 超时后,可以使用 Refresh Token 进行刷新,比如为 Refresh Token 的有效期较长一点比如 6 小时。

Refresh Token 刷新结果有两种:

1若 Access Token 已超时,那么进行 Refresh Token 会获取一个新的 Access Token,新的超时时间;
2若 Access Token 未超时,那么进行 Refresh Token 不会改变 Access Token,但超时时间会刷新,相当于续期 Access Token。

微信小程序登录

登录流程

微信用户指的是已经登录了微信的用户准备使用微信登录第三方平台

第三方应用指的是我们正在开发的小程序或者网站应用。

第一步:请求Code

(对应授权码模式1.2.3)

第三方网站使用微信授权登录时要确保网站域名获得微信授权,微信小程序在微信开发平台上注册好了。

前端开发者发送请求

https://open.weixin.qq.com/connect/qrconnect?
appid=APPID&
redirect_uri=REDIRECT_URI&
response_type=code&
scope=SCOPE&
state=STATE#wechat_redirect
参数是否必须说明
appid应用唯一标识,已经注册好了
redirect_uri请使用urlEncode对链接进行处理
response_type填code
scope应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login
state用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
lang界面语言,支持cn(中文简体)与en(英文),默认为cn

用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数

redirect_uri?code=CODE&state=STATE

若用户禁止授权,则不会发生重定向。

第二步:通过code获取access_token和openid

通过code获取access_token

https://api.weixin.qq.com/sns/oauth2/access_token?
appid=APPID&
secret=SECRET&
code=CODE&
grant_type=authorization_code

参数说明

参数是否必须说明
appid应用唯一标识,在微信开放平台提交应用审核通过后获得
secret应用密钥AppSecret,在微信开放平台提交应用审核通过后获得
code填写第一步获取的code参数
grant_type填authorization_code

返回说明

正确的返回:

{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID", 
"scope":"SCOPE",
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

参数说明

参数说明
access_token接口调用凭证
expires_inaccess_token接口调用凭证超时时间,单位(秒)
refresh_token用户刷新access_token
openid授权用户唯一标识
scope用户授权的作用域,使用逗号(,)分隔
unionid当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。

错误返回样例:

{"errcode":40029,"errmsg":"invalid code"}

刷新access_token有效期

access_token是调用授权关系接口的调用凭证,由于access_token有效期(目前为2个小时)较短,当access_token超时后,可以使用refresh_token进行刷新,access_token刷新结果有两种:

1. 若access_token已超时,那么进行refresh_token会获取一个新的access_token,新的超时时间;
2. 若access_token未超时,那么进行refresh_token不会改变access_token,但超时时间会刷新,相当于续期access_token。

refresh_token拥有较长的有效期(30天),当refresh_token失效的后,需要用户重新授权。

请求方法

获取第一步的code后,请求以下链接进行refresh_token:

https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN

参数说明

参数是否必须说明
appid应用唯一标识
grant_type填refresh_token
refresh_token填写通过access_token获取到的refresh_token参数

返回说明

正确的返回:

{ 
"access_token":"ACCESS_TOKEN", 
"expires_in":7200, 
"refresh_token":"REFRESH_TOKEN", 
"openid":"OPENID", 
"scope":"SCOPE" 
}

参数说明

参数说明
access_token接口调用凭证(调用微信的接口)
expires_inaccess_token接口调用凭证超时时间,单位(秒)
refresh_token用户刷新access_token
openid授权用户唯一标识
scope用户授权的作用域,使用逗号(,)分隔

错误返回样例:

{"errcode":40030,"errmsg":"invalid refresh_token"}

注意:

1、Appsecret 是应用接口使用密钥,泄漏后将可能导致应用数据泄漏、应用的用户数据泄漏等高风险后果;存储在客户端,极有可能被恶意窃取(如反编译获取Appsecret);
2、access_token 为用户授权第三方应用发起接口调用的凭证(相当于用户登录态),存储在客户端,可能出现恶意获取access_token 后导致的用户数据泄漏、用户微信相关接口功能被恶意发起等行为;
3、refresh_token 为用户授权第三方应用的长效凭证,仅用于刷新access_token,但泄漏后相当于access_token 泄漏,风险同上;
4、如无特别业务需求,建议开发者自行管理业务登录态并合理设置过期时间,减少用户重新授权登录次数,优化用户体验。

建议将secret、用户数据(如access_token)放在App云端服务器,由云端中转接口调用请求。

第三步:通过access_token调用接口

获取access_token后,进行接口调用,有以下前提:

1. access_token有效且未超时;
2. 微信用户已授权给第三方应用账号相应接口作用域(scope)。

对于接口作用域(scope),能调用的接口有以下:

授权作用域(scope)接口接口说明
snsapi_base/sns/oauth2/access_token通过code换取access_token、refresh_token和已授权scope
snsapi_base/sns/oauth2/refresh_token刷新或续期access_token使用
snsapi_base/sns/auth检查access_token有效性
snsapi_userinfo/sns/userinfo获取用户个人信息

其中snsapi_base属于基础接口,若应用已拥有其它scope权限,则默认拥有snsapi_base的权限。使用snsapi_base可以让移动端网页授权绕过跳转授权登录页请求用户授权的动作,直接跳转第三方网页带上授权临时票据(code),但会使得用户已授权作用域(scope)仅为snsapi_base,从而导致无法获取到需要用户授权才允许获得的数据和基础功能。

 实践优化

自行管理业务登录态并合理设置过期时间,减少用户重新授权登录次数,优化用户体验。

 这里的session_key其实就是access_token,用来调用微信的接口,是微信的用户状态

第一步:请求Code

在上图中省略了这步。前端通过向微信发送请求,得到了授权码code。

第二步:通过code获取access_token和openid

向微信平台发送请求得到access_token(session_key)和openid

第三步:通过opeanid查询用户状态

查询用户是否是未注册状态,如果未注册,使用微信头像和用户名等信息进行注册。

第四步:生成token返回前端

根据用户的id生成token返回前端

第五步:配置拦截器进行权限验证

 

 

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值