这里是在tp3.2里面写的,但是对框架没有什么太大的依赖,很容易修改
需要配置的参数
//Github 配置
'GITHUB' => array(
'CLIENT_ID' => '',
'CLIENT_SECRET' => '',
),
首先是用户登录的页面,直接跳转GitHub的授权页面
public function login(){
// 记录回跳地址
$return_url=$_SERVER["HTTP_REFERER"]?$_SERVER["HTTP_REFERER"]:__ROOT__;
cookie("return_url",$return_url);
// 跳转 Github 登录页面
redirect("https://github.com/login/oauth/authorize?client_id=".C("GITHUB.CLIENT_ID"));
}
接着是Github的响应地址
// Github 回调地址
public function githubCallback(){
$github_code=I("get.code");
// 向 GitHub 发送 post 请求,请求 access_token
$post_data = http_build_query(
array(
"client_id" => C("GITHUB.CLIENT_ID"),
"client_secret" => C("GITHUB.CLIENT_SECRET"),
"code" => $github_code
)
);
$post_request_options= array(
"http" => array(
"method" => "POST",
"header" => "Content-type:application/x-www-form-urlencoded",
"content" => $post_data,
"timeout" => 15 * 60
)
);
$context = stream_context_create($post_request_options);
$access_token = file_get_contents("https://github.com/login/oauth/access_token", false, $context);
// 向 Github 请求用户信息
ini_set("user_agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)");
$user_info = json_decode(file_get_contents("https://api.github.com/user?".$access_token),true);
// 登录操作
$user_model=new \Home\Model\UserModel();
$user_model->login($user_info);
// 回跳
redirect(cookie("return_url"));
}
为什么请求 access_token 要用 post 而不是 get ?
根据官方的文档,请求 access_token 应该用 post
Users are redirected back to your site by GitHub
请求用户信息的时候为什么要设置 http 请求报文头?
实测,如果直接使用 file_get_contents() 请求不到用户信息
用户模型 UserModel 中的 login 方法
// 用户登录操作
public function login($user_info){
$user_info=array(
"id" => $user_info["id"],
"node_id" => $user_info["node_id"],
"avatar_url" => $user_info["avatar_url"],
"name" => $user_info["name"]
);
$user_table=M("user");
// 先查找用户是否存在
$user=$user_table->where("id=".(int)$user_info["id"])->find();
if (empty($user)) {
// 用户不存在
$user_table->data($user_info)->add();
}
// 写入session
session("user_info",$user_info);
}