奥门新浦京官方网站PHP实现Google Oauth的登录系统

本文讲述的是如何为你的PHP项目实现Google的Oauth系统。这个示例PHP脚本非常快,对增加你的PHP项目注册当然是很有帮助的。

转载链接:blog.nsfocus.net/rest-api-design-safety/

奥门新浦京官方网站 1

在这之前,我们已经覆盖了包含Facebook、Twitter、Google
plus以及Instagram的Oauth登录系统示例。很遗憾之前我遗漏掉了Google的Oauth登录系统。今天我们就来看一下如何为你的web项目实现Google的Oauth系统。

REST API 安全设计指南。REST的全称是REpresentational State
Transfer,它利用传统Web特点,提出提出一个既适于客户端应用又适于服务端的应用的、统一架构,极大程度上统一及简化了网站架构设计。

PHP 是一种通用开源脚本语言。语法吸收了 C 语言、Java 和 Perl
的特点,利于学习,使用广泛,主要适用于 Web
开发领域,是大多数后端开发者的首选。PHP
作为最受欢迎的编程语言之一,经常出现在各大语言之战中,但到底谁是最好的编程语言呢?这不是文章要讨论的内容本文从众多
PHP 开源库中选出了几款实用有趣的工具,希望对你的学习工作有帮助。1、PHP
日志工具 Monolog
Monolog 是一种支持 PHP 5.3+ 以上的日志记录工具。并为
Symfony2 默认支持。示例代码:2、Excel 操作库 PHPExcelPHPExcel
是一个用来读写 Excel 2007 (OpenXML) 文件的 PHP 库。示例代码:3、PHP
机器学习库 PHP-ML
PHP-ml 是 PHP
的机器学习库。同时包含算法,交叉验证,神经网络,预处理,特征提取等。示例代码:4、PHP
的 OAuth 库 Opauth
Opauth 是一个开源的 PHP 库,提供了 OAuth
认证的支持,让你无需关注不同 Provider
之间的差别,提供统一标准的访问方法。目前支持 Google、Twitter 和
Facebook,其他的 Provider 支持也将陆续提供。同时也支持处理任何 OAuth
认证提供方。5、PHP 调试库 WhoopsWhoops
适用于PHP环境的错误捕获与调试PHP库;
whoops非常容易使用,它提供stack-based错误捕获及超美观的错误查看。6、PHP
缓存库 phpFastCache
phpFastCache 是一个开源的 PHP
缓存库,只提供一个简单的 PHP
文件,可方便集成到已有项目,支持多种缓存方法,包括:apc, memcache,
memcached, wincache, files, pdo and mpdo。可通过简单的 API
来定义缓存的有效时间。示例代码:7、PHP 框架 GuzzleGuzzle 是个 PHP
框架,解决了发送大量 HTTP 请求和创建 web
服务客户端的问题。它包括了创建坚实服务客户端的工具,包括:服务描述来定义
API
的输入和输出,通过分页资源实现资源迭代,尽可能高效的批量发送大量的请求。示例代码:8、CSS-JS合并/压缩
Munee
Munee是一个集图片尺寸调整、CSS-JS合并/压缩、缓存等功能于一身的PHP库。可以在服务器端和客户端缓存资源。它集成了PHP图片操作库Imagine来实现图片尺寸调整和剪切,之后进行缓存。示例代码:9、PHP
模板语言
Twig
Twig是一个灵活,快速,安全的PHP模板语言。它将模板编译成经过优化的原始PHP代码。Twig拥有一个Sandbox模型来检测不可信的模板代码。Twig由一个灵活的词法分析器和语法分析器组成,可以让开发人员定义自己的标签,过滤器并创建自己的DSL。示例代码:10、PHP
爬虫库 Goutte
Goutte 是一个抓取网站数据的 PHP 库。它提供了一个优雅的
API,这使得从远程页面上选择特定元素变得简单。示例代码:

在这之前,我们已经覆盖了包含Facebook、Twitter、Google
plus以及Instagram的Oauth登录系统示例。很遗憾之前我遗漏掉了Google的Oauth登录系统。今天我们就来看一下如何为你的web项目实现Google的Oauth系统。这个示例脚本非常快,对增加你的web项目注册当然是很有帮助的。

目前在三种主流的Web服务实现方案中,REST模式服务相比复杂的SOAP和XML-RPC对比来讲,更加简洁,越来越多的web服务开始使用REST设计并实现。但其缺少安全特性,《REST
API 安全设计指南》就是一个REST
API安全设计的指南,权当抛砖引玉,推荐网站后台设计及网站架构师们阅读。

奥门新浦京官方网站 2

1,REST API 简介

Google Oauth登录系统开发示例

REST的全称是REpresentational State
Transfer,表示表述性无状态传输,无需session,所以每次请求都得带上身份认证信息。rest是基于http协议的,也是无状态的。只是一种架构方式,所以它的安全特性都需我们自己实现,没有现成的。建议所有的请求都通过https协议发送。RESTful
web services 概念的核心就是“资源”。 资源可以用 URI 来表示。客户端使用
HTTP 协议定义的方法来发送请求到这些
URIs,当然可能会导致这些被访问的”资源“状态的改变。HTTP请求对应关系如下:

数据库设计

对于请求的数据一般用json或者xml形式来表示,推荐使用json。

数据库设计很简单,如下所示:

2,身份认证

CREATE TABLE users  
(  
id INT PRIMARY KEY AUTO_INCREMENT,  
email VARCHAR(50) UNIQUE,  
fullname VARCHAR(100),  
firstname VARCHAR(50),  
lastname VARCHAR(50),  
google_id VARCHAR(50),  
gender VARCHAR(10),  
dob VARCHAR(15),  
profile_image TEXT,  
gpluslink TEXT

身份认证包含很多种,有HTTP Basic,HTTP Digest,API
KEY,Oauth,JWK等方式,下面简单讲解下:

1,域名注册

2.1 HTTP Basic

在这里注册或者添加你的域名。

REST由于是无状态的传输,所以每一次请求都得带上身份认证信息,身份认证的方式,身份认证的方式有很多种,第一种便是http
basic,这种方式在客户端要求简单,在服务端实现也非常简单,只需简单配置apache等web服务器即可实现,所以对于简单的服务来说还是挺方便的。但是这种方式安全性较低,就是简单的将用户名和密码base64编码放到header中。

奥门新浦京官方网站 3

正是因为是简单的base64编码存储,切记切记在这种方式下一定得注意使用ssl,不然就是裸奔了。
在某些产品中也是基于这种类似方式,只是没有使用apache的basic机制,而是自己写了认证框架,原理还是一样的,在一次请求中base64解码Authorization字段,再和认证信息做校验。很显然这种方式有问题,认证信息相当于明文传输,另外也没有防暴力破解功能。

域名注册

2.2 API KEY

2,所有权认证

API Key就是经过用户身份认证之后服务端给客户端分配一个API
Key,类似:
一个简单的设计示例如下: client端:

验证您的域名所有权,可以通过HTML文件上传或包括META标记。

server端:

奥门新浦京官方网站 4

client端向服务端注册,服务端给客户端发送响应的api_key以及security_key,注意保存不要泄露,然后客户端根据api_key,secrity_key,timestrap,rest_uri采用hmacsha256算法得到一个hash值sign,构造途中的url发送给服务端。
服务端收到该请求后,首先验证api_key,是否存在,存在则获取该api_key的security_key,接着验证timestrap是否超过时间限制,可依据系统成而定,这样就防止了部分重放攻击,途中的rest_api是从url获取的为/rest/v1/interface/eth0,最后计算sign值,完之后和url中的sign值做校验。这样的设计就防止了数据被篡改。
通过这种API
Key的设计方式加了时间戳防止了部分重放,加了校验,防止了数据被篡改,同时避免了传输用户名和密码,当然了也会有一定的开销。

所有权认证

2.3 Oauth1.0a或者Oauth2

3,OAuth Keys

OAuth协议适用于为外部应用授权访问本站资源的情况。其中的加密机制与HTTP
Digest身份认证相比,安全性更高。使用和配置都比较复杂,这里就不涉及了。

谷歌将提供你OAuth用户密钥和OAuth秘密密钥。

2.4 JWT

奥门新浦京官方网站 5

JWT 是JSON Web
Token,用于发送可通过数字签名和认证的东西,它包含一个紧凑的,URL安全的JSON对象,服务端可通过解析该值来验证是否有操作权限,是否过期等安全性检查。由于其紧凑的特点,可放在url中或者
HTTP Authorization头中,具体的算法就如下图

Oauth keys

3 授权

4, Google API控制台

身份认证之后就是授权,根据不同的身份,授予不同的访问权限。比如admin用户,普通用户,auditor用户都是不同的身份。简单的示例:

在Google
API控制台创建客户端ID。

上述是垂直权限的处理,如果遇到了平行权限的问题,如用户A获取用户B的身份信息或者更改其他用户信息,对于这些敏感数据接口都需要加上对用户的判断,这一步一般都在具体的逻辑实现中实现。

奥门新浦京官方网站 6

4 URL过滤

Google API控制台

在进入逻辑处理之前,加入对URL的参数过滤,如

奥门新浦京官方网站 7

限定num位置为整数等,如果不是参数则直接返回非法参数,设定一个url清单,不在不在url清单中的请求直接拒绝,这样能防止开发中的api泄露。rest
api接口一般会用到GET,POST,PUT,DELETE,未实现的方法则直接返回方法不允许,对于POST,PUT方法的数据采用json格式,并且在进入逻辑前验证是否json,不合法返回json格式错误。

Google API控制台

5 重要功能加密传输

然后你就可以看见你的客户端ID和密钥。

第一步推荐SSL加密传输,同时对于系统中重要的功能做加密传输,如证书,一些数据,配置的备份功能,同时还得确保具备相应的权限,这一步会在授权中涉及。

奥门新浦京官方网站 8

6 速率限制

配置好的Google Oauth信息

请求速率限制,根据api_key或者用户来判断某段时间的请求次数,将该数据更新到内存数据库(redis,memcached),达到最大数即不接受该用户的请求,同时这样还可以利用到内存数据库key在特定时间自动过期的特性。在php中可以使用APC,AlternativePHPCache
(APC)
是一个开放自由的PHPopcode
缓存。它的目标是提供一个自由、
开放,和健全的框架用于缓存和优化PHP的中间代码。在返回时设置X-Rate-Limit-Reset:当前时间段剩余秒数,APC的示例代码如下:

config.php

7 错误处理

你可以在src文件夹找到这个文件,在这里您需要配置应用程序OAuth密钥,Consumer
keys和重定向回调URL。

对于非法的,导致系统出错的等请求都进行记录,一些重要的操作,如登录,注册等都通过日志接口输出展示。有一个统一的出错接口,对于400系列和500系列的错误都有相应的错误码和相关消息提示,如401:未授权;403:已经鉴权,但是没有相应权限。如不识别的url:

// OAuth2 Settings, you can get these keys at https://code.google.com/apis/console Step 6 keys  
'oauth2_client_id' => 'App Client ID',  
'oauth2_client_secret' => 'App Client Secret',  
'oauth2_redirect_uri' => 'http://yoursite.com/gplus/index.php',  

// OAuth1 Settings Step 3  keys.  
'oauth_consumer_key' => 'OAuth Consumer Key',  
'oauth_consumer_secret' => 'OAuth Consumer Secret',

,错误的请求参数

google_login.php

,不允许的方法:

Google plus登录系统,你只需要在index.php中加载这个文件。

,非法参数等。上面所说的都是单状态码,同时还有多状态码,表示部分成功,部分字符非法等。示例如下:

<?php  
require_once 'src/apiClient.php';  
require_once 'src/contrib/apiOauth2Service.php';  
session_start();  
$client = new apiClient();  
setApplicationName("Google Account Login");  
$oauth2 = new apiOauth2Service($client);  
if (isset($_GET['code']))  
{  
$client->authenticate();  
$_SESSION['token'] = $client->getAccessToken();  
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];  
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));  
}  
if (isset($_SESSION['token'])) {  
$client->setAccessToken($_SESSION['token']);  
}  
if (isset($_REQUEST['logout'])) {  
unset($_SESSION['token']);  
unset($_SESSION['google_data']); //Google session data unset  
$client->revokeToken();  
}  
if ($client->getAccessToken())  
{  
$user = $oauth2->userinfo->get();  
$_SESSION['google_data']=$user; // Storing Google User Data in Session  
header("location: home.php");  
$_SESSION['token'] = $client->getAccessToken();  
} else {  
$authUrl = $client->createAuthUrl();  
}  
if(isset($personMarkup)):  
print $personMarkup;  
endif 
if(isset($authUrl))  
{  
echo "<a class="login" href="$authUrl">Google Account Login</a>";  
} else {  
echo "<a class="logout" href="?logout">Logout</a>";  
}  
?>

8 重要ID不透明处理

home.php

在系统一些敏感功能上,比如/user/1123
可获取id=1123用户的信息,为了防止字典遍历攻击,可对id进行url62或者uuid处理,这样处理的id是唯一的,并且还是字符安全的。

在这里我们需要向之前创建的user表插入Google plus的session信息。代码如下:

9 其他注意事项

<?php  
session_start();  
include('db.php'); //Database Connection.  
if (!isset($_SESSION['google_data'])) {  
// Redirection to application home page.  
header("location: index.php");  
}  
else 
{  
//echo print_r($userdata);  
$userdata=$_SESSION['google_data'];  
$email =$userdata['email'];  
$googleid =$userdata['id'];  
$fullName =$userdata['name'];  
$firstName=$userdata['given_name'];  
$lastName=$userdata['family_name'];  
$gplusURL=$userdata['link'];  
$avatar=$userdata['picture'];  
$gender=$userdata['gender'];  
$dob=$userdata['birthday'];  
//Execture query  
$sql=mysql_query("insert into users(email,fullname,firstname,lastname,google_id,gender,dob,profile_image,gpluslink) values('$email','$fullName','$firstName','$lastName','$googleid','$gender','$dob','$avatar','$gplusURL')");  
?>

(1)请求数据,对于POST,DELETE方法中的数据都采用json格式,当然不是说rest架构不支持xml,由于xml太不好解析,对于大部分的应用json已经足够,近一些的趋势也是json越来越流行,并且json格式也不会有xml的一些安全问题,如xxe。使用json格式目前能防止扫描器自动扫描。
(2)返回数据统一编码格式,统一返回类型,如Content-Type:
application/json; charset=”UTF-8″
(3)在逻辑实现中,json解码之后进行参数验证或者转义操作,第一步json格式验证,第二步具体参数验证基本上能防止大部分的注入问题了。
(4)在传输过程中,采用SSL保证传输安全。
(5)存储安全,重要信息加密存储,如认证信息hash保存。

db.php

总之,尽量使用SSL。

数据库配置文件。

<?php  
$mysql_hostname = "localhost";  
$mysql_user = "username";  
$mysql_password = "password";  
$mysql_database = "databasename";  
$bd = mysql_connect($mysql_hostname, $mysql_user, $mysql_password) or die("Could not connect database");  
mysql_select_db($mysql_database, $bd) or die("Could not select database");  
?>

发表评论

电子邮件地址不会被公开。 必填项已用*标注