OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版。
本文例子为 在多个不同域名的网站下,使用同一套用户中心体系,点击登录跳转到已搭建 OAuth2.0
的服务端后,用户授权登录。
(A)用户访问客户端,后者将前者导向认证服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的”重定向URI”(redirection URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的”重定向URI”,向认证服务器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access_token)和更新令牌(refresh_token)。
(F)客户端用 access_token 向认证服务器获取用户信息
搭建 OAuth2.0
的服务端 简称 i.com
步骤A
用户在 a.com
网站上点击登录,网站带上参数跳转到 i.com
参数:
response_type:表示授权类型,必选项
client_id:表示客户端的ID,必选项
redirect_uri:表示重定向URI,可选项
scope:表示申请的权限范围,可选项
state:表示客户端的当前状态,可以指定任意值,认证服务器会原封不动地返回这个值。
例如:
GET
http://i.com/authorize?response_type=login&client_id= {%client_id%} &redirect_uri=http%3A%2F%2Fa%2Ecom
HTTP/1.1
Host: a.com
步骤B
i.com
根据 client_id
去数据库 client
表查找是否存在 client_id
,存在则根据cookie或者其它方式验证用户是否在 i.com
为登录状态。
有登录则出现授权界面让用户确认是否授权,没有则进入正常用户帐号密码登录流程,登录成功后则出现授权界面让用户确认是否授权。
步骤C
当用户确认授权后,i.com
根据 client_id
搜出来数据 $data
,生成 $code
和 $redirect_uri
和 $expires
,等信息并保存到 code
表中,code有效期为60秒内,
最后跳转回 client
表中根据 client_id
搜索出来的 $data['redirect_uri']
。
$code = md5($client_id.$user_id.date("YmdHis",time()));
$redirect_uri = $data['redirect_uri'].'?code='.$code;
$expires = time()+60;
//保存数据到 code 表中
...
$url = $redirect_uri.'&client_id='$client_id.'&referer_url='.$_GET['redirect_uri'];
header("Location:".$url);
步骤D
i.com
收到 $_GET['code']
和 $_GET['client_id']
后,
POST http://i.com/token HTTP/1.1
Host: a.com
code= {%code%} &client_id= {%client_id%} &client_secret= {%client_secret%}
步骤E
服务器 i.com
接收到 code
、client_id
、client_secret
后,验证 code
表,验证通过后生成 $access_token
和 $refresh_token
和 $expires
, 保存到 token
表中后,发送的HTTP回复到 a.com
,包含以下参数:
$access_token = md5($client_id.$user_id.date("YmdHis",time()));
$refresh_token = md5($client_id.$client_secret.date("Ymd",time()));
$expires = time()+3600; //access_token有效期为1小时
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
"access_token" : "example",
"token_type" : "example",
"expires_in" : 3600,
"refresh_token" : "example"
}
access_token:表示访问令牌,必选项。
token_type:表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型。
expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。
步骤F
a.com
用收到的 access_token
向 i.com
获取用户信息并在 a.com
下存cookie或其它方式进行登录。
附上数据表
CREATE TABLE `oauth_client` (
`id` bigint(20) NOT NULL auto_increment,
`client_id` varchar(32) NOT NULL,
`client_secret` varchar(32) NOT NULL,
`redirect_uri` varchar(200) NOT NULL,
`create_time` int(20) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
CREATE TABLE `oauth_code` (
`id` bigint(20) NOT NULL auto_increment,
`client_id` varchar(32) NOT NULL,
`user_id` varchar(32) NOT NULL,
`code` varchar(40) NOT NULL,
`redirect_uri` varchar(200) NOT NULL,
`expires` int(11) NOT NULL,
`scope` varchar(250) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `oauth_token` (
`id` bigint(20) NOT NULL auto_increment,
`client_id` varchar(32) NOT NULL,
`user_id` varchar(32) NOT NULL,
`access_token` varchar(40) NOT NULL,
`refresh_token` varchar(40) NOT NULL,
`expires` int(11) NOT NULL,
`scope` varchar(200) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
**(文章写的估计外人都看不懂了,没关系,我是写给我自己看的。。。请原谅~)
** 配合用户中心同步机制可实现多网站同步登录(详情请用力戳我),方可实现一次登录,多个域名网站同步登录。