github 官网文档

https://docs.github.com/cn/developers/apps/building-oauth-apps/authorizing-oauth-apps#web-application-flow

原理

  • 客户端发起请求 redirect 到 OAuth 接入方并附带上 client_id
  • 用户在 redirect 之后的网站上输入用户名和密码
  • 登陆成功之后,OAuth 接入方会返回给服务端一个 code。
  • 服务端拿到 code 之后,拿着 client_secret 和 code 向 OAuth 接入方申请获得 Token
  • 服务端拿到 Token 之后,进入授权窗口
  • 授权成功,跳转到客户端网站。

创建好 github 账号后点击设置

之后进入前期工作

github 页面开通

步骤一

步骤二

步骤三

步骤四添加好必填项

注册应用后会生成 client_id, 然后需要创建密码

1
2
3
4
#页面首页地址(登录成功后跳转到的地址):
http://huicmf.frp.toushizhiku.com:18080/app/user
#授权回调地址(代码中处理函数逻辑的请求地址):
http://huicmf.frp.toushizhiku.com:18080/app/user/github

代码实现

配置好之后接下来是代码实现

1
2
3
4
5
6
7
<a
class="tooltips"
href="https://github.com/login/oauth/authorize?client_id=Ov23li51234Of&redirect_uri=%2F"
title="使用GitHub一键登录"
>
<img src="__STATIC__/images/github.png" alt="GitHub" />
</a>

方法函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
public function github(Request $request)
{
try {
$time = time();
// 如果已登录,直接跳转
if ($request->session()->has('session_userInfo')) {
return redirect('/app/user');
}
// GitHub应用程序的客户端ID和密钥
$client_id = "";
$client_secret = "";
$redirect_uri = $request->get('redirect_url', $request->path());
$code = $request->get('code');
if (empty($code)) {
return redirect('https://github.com/login/oauth/authorize?client_id='.$client_id.'&redirect_url='.urlencode($redirect_uri).'&scope=user');
}
$options = [
'http' => [
'header' => "Content-Type: application/x-www-form-urlencoded\r\nAccept: application/json\r\nUser-Agent: {$request->header('user-agent')}\r\n",
'method' => 'POST',
'content' => http_build_query([
'client_id' => $client_id,
'client_secret' => $client_secret,
'code' => $code
])
]
];
$context = stream_context_create($options);
$response = file_get_contents('https://github.com/login/oauth/access_token', false, $context);
$params = json_decode($response, true);
$access_token = $params['access_token'];
// 使用访问令牌访问GitHub API
$options = array(
'http' => array(
'header' => "Authorization: Bearer $access_token\r\nAccept: application/json\r\nUser-Agent: {$request->header('user-agent')}\r\n",
'method' => 'GET',
'timeout' => 120
)
);
$context = stream_context_create($options);
$user_info = file_get_contents('https://api.github.com/user', false, $context);
$user_data = json_decode($user_info, true);

$getIp = $request->getRealIp();
$user = UserModel::where(['email' => $user_data['email']])->find();

//这一部分是授权成功后处理用户信息(写入或更新数据表数据,可参考,改成自己的)
if (empty($user)) {
$data = [
'username' => $user_data['login'],
'nickname' => $user_data['name'],
'email' => $user_data['email'],
'avatar' => $user_data['avatar_url'],
'last_time' => $time,
'last_ip' => $getIp,
'status' => 1,
'join_time' => $time,
'join_ip' => $getIp,
'check_email' => 1,
'mobile' => "",
'level' => 0,
'role' => 0,
'end_time' => 0
];
$user = UserModel::create($data);
$sessionUser = $user->toArray();
} else {
$user->last_ip = $getIp;
$user->last_time = $time;
$user->save();

$sessionUser = $user->toArray();
$sessionUser['last_ip'] = $getIp;
$sessionUser['last_time'] = $time;
$sessionUser['update_time'] = $time;
unset($sessionUser['password']);
unset($sessionUser['salt']);
}
// end

$request->session()->set('session_userInfo', $sessionUser);

return redirect($redirect_uri);
} catch (\Throwable $throwable) {
return $this->transfer('github授权出错了');
}
}

protected function transfer(string $msg, int $time = 3000)
{
return response("<div style=\"display: flex;justify-content: center;padding: 30px;width: 100%;color: #F56E0DFF;\">$msg</div><script>setTimeout(function(){
window.location.href = '/';
}, {$time})</script>");
}

完成,收工。