Авторизация на сайте через GitHub

Авторизация на сайте через GitHub

GitHub имеет свой API для авторизации по OAuth, что позволяет сделать авторизацию зарегистрированных там пользователей на своем сайте. Далее инструкция, как получить данные пользователя.

Документация https://docs.github.com/en/developers/apps/creating-an-oauth-app

Регистрация приложения

После авторизации на GitHub, нужно создать приложение на странице https://github.com/settings/applications/new.

В форме указываем название вашего приложения, адрес, описание сайта и callback URL – адрес скрипта для обработки авторизации (можно указать только один URL).

После отправки формы получаем Client ID и Client secrets:

Ссылка для входа

На вашей странице авторизации формируем ссылку для входа:

$params = array(
	'client_id'     => 'Client_ID',
	'redirect_uri'  => 'https://ваш_домен/oauth-github.php',
	'scope'         => 'user',
	'response_type' => 'code',
	'state'         => ''
);
 
$url = 'https://github.com/login/oauth/authorize?'.urldecode(http_build_query($params));
echo '<a href="'.$url.'">Войти через GitHub</a>';

При переходе по такой ссылке откроется страница на GitHub c подтверждением входа:

Скрипт обработчик

После того, как пользователь подтвердил запрос, он будет перенаправлен на callback URL (https://ваш_домен/oauth-github.php) с GET-параметром «code», содержащий код авторизации. Далее с помощью этого кода получаем access_token, а далее данные пользователя.

<?php
if (!empty($_GET['code'])) {
	$params = array(
		'client_id'     => 'Client_ID',
		'client_secret' => 'Client_secrets',
		'redirect_uri'  => 'https://ваш_домен/oauth-github.php',
		'code'          => $_GET['code']
	);	
			
	$ch = curl_init('https://github.com/login/oauth/access_token');
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_POSTFIELDS, urldecode(http_build_query($params))); 
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_HEADER, false);
	$data = curl_exec($ch);
	curl_close($ch);	
	parse_str($data, $data);
 
	if (!empty($data['access_token'])) {
		$ch = curl_init('https://api.github.com/user');
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
		curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: token '.$data['access_token']));
		curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88');
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		$info = curl_exec($ch);
		curl_close($ch);
		$info = json_decode($info, true);
 
		if (!empty($info['id'])) {
			print_r($info);
		}
	} 
}

* В запросе на https://api.github.com/user нужно обязательно передать User-Agent.

Пример полученных данных пользователя:

Array
(
    [login] => test
    [id] => 99999999
    [node_id] => M3Q6V4Nlcac4Mz6wOTc2
    [avatar_url] => https://avatars.githubusercontent.com/u/99999999?v=4
    [gravatar_id] => 
    [url] => https://api.github.com/users/test
    [html_url] => https://github.com/test
    [followers_url] => https://api.github.com/users/test/followers
    [following_url] => https://api.github.com/users/test/following{/other_user}
    [gists_url] => https://api.github.com/users/test/gists{/gist_id}
    [starred_url] => https://api.github.com/users/test/starred{/owner}{/repo}
    [subscriptions_url] => https://api.github.com/users/test/subscriptions
    [organizations_url] => https://api.github.com/users/test/orgs
    [repos_url] => https://api.github.com/users/test/repos
    [events_url] => https://api.github.com/users/test/events{/privacy}
    [received_events_url] => https://api.github.com/users/test/received_events
    [type] => User
    [site_admin] => 
    [name] => 
    [company] => 
    [blog] => 
    [location] => 
    [email] => 
    [hireable] => 
    [bio] => 
    [twitter_username] => 
    [public_repos] => 0
    [public_gists] => 0
    [followers] => 0
    [following] => 0
    [created_at] => 2021-02-01T16:15:42Z
    [updated_at] => 2021-02-01T16:15:43Z
    [private_gists] => 0
    [total_private_repos] => 0
    [owned_private_repos] => 0
    [disk_usage] => 0
    [collaborators] => 0
    [two_factor_authentication] => 
    [plan] => Array(
		[name] => free
		[space] => 976562499
		[collaborators] => 0
		[private_repos] => 10000
	)
)

Дальнейшее применение полученных данных завит от реализации сайта, пользователя можно добавить в БД или обновить его данные и авторизовать в системе.