认证一直是网络生活中最常见的问题。
1.0 常见的认证协议
1.1OAuth
允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据。每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频)。这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问许可或他们数据的所有内容。
1.2 OAuth2.0
是OAuth协议的下一版本,但不向后兼容OAuth 1.0。 OAuth 2.0关注客户端开发者的简易性,同时为Web应用,桌面应用和手机,和起居室设备提供专门的认证流程。2012年10月,OAuth 2.0协议正式发布为RFC 6749
1.3 举例具体流程:
获取百度开发者平台的accesstoken
发送请求到baidu服务器,携带必要的参数,会返回一个token;
服务器返回的JSON文本参数如下:
access_token:要获取的Access Token;
expires_in:Access Token的有效期(秒为单位,一般为1个月);
其他参数忽略,暂时不用;
import urllib, urllib2
import sys,ssl
import json, os
import time, base64
import cv2,ctypes
appid='自己搞定'
appkey='自己搞定'
SecretKey='自己搞定'
#获取百度接口调用需要的accesstoken
def getAccessToken():
# 这里accessToken需要缓存在文件中以保证不频繁请求
path='./accesstoeken'
with open(path, 'r+') as f:
content=f.read()
if len(content)>10:
modifyTime=os.path.getmtime(path)
nowTime=time.time()
js=json.loads(content)
if nowTime-modifyTime>js['expires_in']:
print 'time out limit'
#requist access token
else:
return js['access_token']
#重新请求accesstoken
host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id='+appkey+'&client_secret='+SecretKey
request = urllib2.Request(host)
request.add_header('Content-Type', 'application/json; charset=UTF-8')
response = urllib2.urlopen(request)
content = response.read()
#持久化
f.write(content)
js=json.loads(content)
return js['access_token']
1.4 微信公众号开发
1.4.1 微信接入
const APPID='...';
const APPSECRET='...';
const TOKEN='...';
require_once("./WeChat.class.php");
$wechat=new WeChat(APPID,APPSECRET,TOKEN);
if (isset($_GET['echostr'])) {
$wechat->valid();
}else{
$wechat->responseMsg();
}
//这里直接上微信开发那里找就行了
public function valid()//检查安全性
{
$echoStr = $_GET["echostr"];
//valid signature , option
if($this->checkSignature()){//检查签名是否一致
echo $echoStr;//验证成功后,输出
exit;
}
}
/**
* 微信服务器认证
* @return bool
*/
private function checkSignature()
{
$signature =$_GET["signature"];
$timestamp =$_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = $this->TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
1.4.2微信授权登录
获取用户信息流程:
1.4.2.1手机端认证登录
1.4.2.2多端认证登录:
场景:电脑端点击登录,弹出二维码,手机扫码,确认后电脑成功登录
1.4.3 微信公众号回复
主页的消息分流和服务器身份验证
/**
* 主消息分流,和验证
*/
public function index(){
if (isset($_GET['echostr'])) {
$this->wechat->valid();
}else{
$this->wechat->responseMsg();
}
}
wechat 类的消息分流方法
/**
* 消息响应分流
*/
public function responseMsg()
{
// //get post data, May be due to the different environments
$postStr = file_get_contents('php://input');//获得用户发送信息
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$this->log->pushDebug(__METHOD__."MsgType:\t".$postObj->MsgType);
switch($postObj->MsgType){
case 'event':
$this->doEvent($postObj);
break;
case 'text':
$this->doText($postObj);
break;
case 'image':
$this->doImage($postObj);
break;
case 'voice':
$this->doVoice($postObj);
break;
case 'video':
$this->doVideo($postObj);
break;
case 'location':
$this->doLocation($postObj);
break;
case 'shortvideo':
$this->doShortVideo($postObj);
break;
case 'link':
$this->doLink($postObj);
break;
default: exit;
}
}
回复信息的方法
/**
* 回复
* @param $postObj
*/
private function doText($postObj){
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$keyword = trim($postObj->Content);
$time = time();
$textTpl = "
%s
0
";
if(!empty( $keyword ))
{
$data = "chat=".$keyword;
$contentStr="hello world!";
if($keyword == "hello")
$contentStr = "Welcome to Wechat PHP 39 world!";
if($keyword == "PHP")
$contentStr = "最流行的网页编程语言!";
if($keyword == "JAVA")
$contentStr = "较流行的网页编程语言!";
$msgType = "text";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
//清除多余信息
ob_clean();
echo $resultStr;
}
exit;
}
具体的其他接口信息参照微信相关文档。顺便吐槽一句,微信的文档并没有百度容易理解,而阿里的文档则更全面一些,也是难懂的。