一.OAuth2.0协议核心概念
(1)OAuth2.0协议
OAuth协议一般用于用户决定是否把自己在某个服务商上面的资源(比如:用户基本资料、照片、视频等)授权给第三方应用访问。此外,OAuth2.0协议是OAuth协议的升级版,现在已经逐渐成为单点登录(SSO)和用户授权的标准。
不知道大家有没有发现,目前主流的互联网网站除了可以使用“用户名+密码”模式和“手机号+验证码”模式登录外,很多还提供了第三方账号登录,比如最常见的QQ登录、微博登录、百度账号登录、GitHub登录。而这些第三方登录方式就是采用了OAuth2.0协议实现。
(2)为什么使用OAuth2.0协议
第一,用户不再需要注册大量账号。
第二,用于单点登录 所有需要登录的产品都请求同一个登录授权中心,进行统一登录授权处理
(3)OAuth2.0协议涉及的几个角色
授权服务端应用(Authorization Server):服务提供商提供的专门用于处理授权的服务端应用,比如上面介绍的QQ登录、微博登录,当然也可以搭建自己的授权服务端,发放Access Token
资源服务应用(Resource Server):服务提供商存放用户及其他资源的应用,一般用于接口的形式返回第三方应用请求的资源。它可以与授权服务端属于同一个应用,也可以分别属于不同的应用。
用户(User):用户在授权服务端登录,授权服务端记录了用户的账户体系。当然,有的网站会在你通过第三方账号第一次登录成功后,要求绑定你的手机号并创建昵称,这就是他们在创建自己的账户体系(跟OAuth2.0协议无关,这里不作展开)了。
接入的第三方应用(Third-party Application):接入认证的第三方应用又被称为“客户端”,比如一个普通的网站、APP。
(4)几种授权模式
授权码模式(authorization code):四种授权中授权码方式是最为复杂,但也是安全系数最高的,比较常用的一种方式。这种方式适用于兼具前后端的Web项目,因为有些项目只有后端或只有前端,并不适用授权码模式。
简化模式(implicit):跳过了请求授权码(Authorization Code)的步骤,直接通过浏览器向授权服务端请求令牌(Access Token)。这种模式的特点是所有步骤都在浏览器中完成,Token对用户可见,且请求令牌的时候不需要传递client_secret进行客户端认证。
密码模式(resource owner password credentials):用户向第三方客户端提供自己在授权服务端的用户名和密码,客户端通过用户提供的用户名和密码向授权服务端请求令牌(Access Token)。
(5)授权码模式(authorization code)授权的流程
- 第三方应用请求用户授权;
- 用户同意授权,并返回一个授权码(code);
- 第三方应用根据授权码(code)向授权认证服务进行授权;
- 授权服务器根据授权码(code),校验通过,并返回给第三方应用令牌(Access Token);
- 第三方应用根据令牌(Access Token)向资源服务请求相关资源;
- 资源服务器验证令牌(Access Token),校验通过,并返回第三方所请求的资源。
二.使用授权码模式实现统一认证中心登录
(1)获取Authorization Code
其获取方式是通过重定向用户浏览器(或手机/桌面应用中的浏览器组件)到https://login.netease.com/connect/authorize地址,
并带上以下参数:
- client_id:必须参数,注册应用时获得的API Key。授权服务器发放
- response_type:必须参数,此值固定为“code”。
- redirect_uri:必须参数,授权后要跳转回调的URI,即接收Authorization Code的URI。
- scope:指定了客户端请求的权限范围(scope),身份信息(openid)、全名(fullname)、昵称(nickname)、邮箱(email)、员工号(empno)、区域代码(areacode)等。客户端请求的权限范围将影响授权服务器授予的访问令牌的权限。
- state:非必须参数,随机数
state说明:
OAuth中的state参数是用于防止CSRF(跨站请求伪造)攻击的一种安全机制。它是在进行OAuth认证请求时传递的一个随机值,由客户端生成并附加在认证请求中,然后在完成认证后由授权服务器返回给客户端。客户端在接收到授权服务器返回的响应时,需要验证返回的state值是否与发送时的值一致,以确保请求的合法性。
具体来说,state参数的使用方式如下:
- 生成随机值:客户端在发送认证请求之前,生成一个随机的state值,并将其附加在认证请求中。
- 传递给授权服务器:客户端将生成的state值作为参数附加在认证请求中,发送给授权服务器。
- 返回给客户端:授权服务器在认证完成后,将生成的state值作为参数附加在回调URL中返回给客户端。
- 验证state值:客户端接收到授权服务器返回的响应后,需要验证返回的state值是否与发送时的值一致。
(2)通过Authorization Code获取Access Token
https://login.netease.com/connect/token通过上面获得的Authorization Code,接下来便可以用其换取一个Access Token
带上以下5个必须参数:
- grant_type:必须参数,此值固定为authorization_code。
- code:必须参数,通过上面第一步所获得的Authorization Code。
- client_id:必须参数,应用的API Key。授权服务器发放
- client_secret:必须参数,应用的Secret Key。授权服务器发放
- redirect_uri:必须参数,该值必须与获取Authorization Code时传递的redirect_uri保持一致。
响应数据包格式:
- access_token:要获取的Access Token。
- expires_in:Access Token的有效期,以秒为单位(30天的有效期)。
- refresh_token:用于刷新Access Token 的 Refresh Token,所有应用都会返回该参数(10年的有效期)。
- scope:Access Token最终的访问范围,即用户实际授予的权限列表(用户在授权页面时,有可能会取消掉某些请求的权限)。
- session_key:基于http调用Open API时所需要的Session Key,其有效期与Access Token一致。
- session_secret:基于http调用Open API时计算参数签名用的签名密钥。
(2)使用Access Token获取用户的基本资料
https://login.netease.com/connect/userinfo?access_token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx