Для начала обозначим все необходимое:
Шаг 1. Создадим локальный сервер
Создай папку и назови ее как хочешь. Это будет директория твоего проекта, где будет твой код.
Самый первый файл добавим package.json. Он поможет нам отображать зависимости проекта и использовать разные команды для запуска кода.
{
"name": "vk-oauth",
"description": "description",
"authors": "author",
"version": "1.0.0",
"dependencies": {}
}
Далее index.js тут мы инициализируем наш сервер. Добавим следующий код:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => res.send('Hello World!'));
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`));
Отлично. Не забудь сохранить файл.
В коде видно, что мы используем express, это фрэймворк для node.js. Но у нас его нет в зависимостях. Для этого необходимо открыть терминал в проекте и написать:
yarn add express
Взгляни на файл package.json, он должен измениться
"dependencies": {
"express": "^4.17.1"
}
Теперь нужно как-то запустить этот сервер, хм... Добавим скрипты в этот же файл:
"scripts": {
"start": "yarn && node index"
},
Вот так должен выглядеть полный файл package.json:
{
"name": "vk-oauth",
"description": "description",
"authors": "author",
"version": "1.0.0",
"scripts": {
"start": "yarn && node index"
},
"dependencies": {
"express": "^4.17.1"
}
}
Теперь запустим наш сервер используя команду:
yarn start
Открой в браузере http://localhost:3000 и ты должен увидеть Hello World!, если все получилось.
Идем далее.
Шаг 2. Настройка приложения вк
Для того, чтобы использовать vk api нам нужно приложение. Переходим сюда и создаем приложение.
Как только создал приложение, то переходи в настройки слева. Тут будут ключи, которые позволят вызвать методы vk api.
Шаг 3. Безопасное внедрение ключей в код.
Установим dotenv пакет, он позволит нам читать строки из файла .env.
В терминале напиши:
yarn add dotenv
Теперь создай файл .env и добавть такие строки
VK_APP_ID=666666
VK_APP_SECRET=66666666666666
На скрине видно в каких строках нужно заменить шестерки.
В index.js на 4 строку добавим инициализацию dotenv
require('dotenv').config();
Отлично. Ключи для vk api готовы к использованию.
Шаг 4. Вызов методов для авторизации
Создадим папку vk-auth и добавим туда два пустых файла: index.js и helpers.js.
Сперва напишем код в helpers. Тут будут вспомогательные функции, которые помогут сохранить наш код чистым.
Первая функция callApi она будет вызывать методы. Для нее нам нужно добавить axios - это http клиент, один из самых мощных.
В терминале напишем:
yarn add axios
Теперь добавим код в файл helpers.js
const axios = require('axios');
exports.callApi = async (
method,
url,
payload = null
) => {
try {
const payloadString = payload !== null ? JSON.stringify(payload) : null;
const rc = {
url,
headers: {
Accept: 'application/json',
},
method,
};
if (payloadString) {
rc.data = payloadString;
rc.headers['Content-Type'] = 'application/json; charset=UTF-8';
}
const result = await axios(rc).then(
(r) => ({ data: r.data, status: r.status }),
(e) => ({ status: e.response.status, error: e.response.data.error })
);
if (!result) {
return {};
}
if (result.status === 400) {
const errMessage = result.error.message;
if (errMessage) {
console.error(errMessage);
return {};
}
return {};
}
return result.data;
} catch (error) {
console.error('fetch api error', error);
return {};
}
};
Весь код по строчкам разбирать не будем. Если есть вопросы, то пиши в комментарии или в соц сети.
Еще нам понадобится вспомогательная функция для того, чтобы красиво записывать query string или строку запросов. Добавим этот код в helpers.js
exports.buildQueryString = (items) => {
const joined = items
.map((it) => {
const key = Object.keys(it)[0];
return `${key}=${encodeURI(it[key])}`;
})
.join('&');
return joined.length > 0 ? '?' + joined : '';
}
Теперь создадим функции запросов к vk api. В файле index.js, который находится в папке vk-auth добавим первые строки:
const { buildQueryString, callApi } = require('./helpers'); // импортируем наших помощников.
const scopes = ['email']; // рамки того, что мы будем запрашивать
// создаем url, который перенаправит нас на вк авторизацию
exports.vKAuthFirstStep = (res) => {
const url = `https://oauth.vk.com/authorize${buildQueryString([
{ client_id: process.env.VK_APP_ID },
{ redirect_uri: 'http://localhost:3000/login/vk/complete' },
{ response_type: 'code' },
{ scope: scopes.join('+') },
{ state: '{}' },
])}`;
res.redirect(url);
};
Теперь в самом главном index.js добавим маршрут, на котором будем вызывать метод выше
const { vKAuthFirstStep } = require('./vk-auth'); // импортируем наш метод
app.get('/login/vk', (req, res) => vKAuthFirstStep(res));
Запустим проект и перейдем сюда http://localhost:3000/login/vk. Должно отобразить окно с вк авторизацией.
Взгляни на метод vKAuthFirstStep тут видно, что для возвращения после авторизации мы указали ссылку возврата, а именно 'http://localhost:3000/login/vk/complete'
Теперь же приступим к созданию метода на этом маршруте login/vk/complete.
В файле index.js, который находится в папке vk-auth добавим следующие методы:
exports.vkLoginComplete = async (req, res) => {
const code = req.query['code'] || '';
if (!code) {
console.debug('Cannot authorize no code')
return res.send('Cannot authorize no code');
};
const data = await getAccessToken(String(code));
if (!data.access_token) {
console.debug('Unable to get access token')
return res.send('Unable to get access token');
}
const userInfo = await getUserInfo(data.access_token);
console.debug('Successfully got information about authorized user');
return res.send(`Successfully got information about authorized user ${JSON.stringify(userInfo)}`)
};
const getAccessToken = async (code) => {
const { email, access_token, user_id } = await callApi(
'post',
`https://oauth.vk.com/access_token${buildQueryString([
{ code: code },
{ client_id: process.env.VK_APP_ID },
{ client_secret: process.env.VK_APP_SECRET },
{ redirect_uri: 'http://localhost:3000/login/vk/complete' },
])}`
);
return {
email,
access_token,
user_id,
};
};
const getUserInfo = async (accessToken) => {
const data = await callApi(
'post',
`https://api.vk.com/method/users.get${buildQueryString([
{ access_token: accessToken },
{ fields: ['screen_name', 'nickname'].join(',') },
])}&v=5.103`
);
const { id, first_name, last_name, screen_name, nickname } = data.response[0];
return {
id: id,
name: nickname || screen_name || first_name + ' ' + last_name,
};
};
getAccessToken необходимо вызвать, чтобы получить специальный ключ, с которым можно получать дополнительную информацию касаемо того пользователя, который сейчас использовал авторизацию вк.
Теперь обновим главный index.js, где добавим последний маршрут login/vk/complete. Так должен выглядеть наш файл:
const express = require('express');
const app = express();
const port = 3000;
require('dotenv').config();
const { vKAuthFirstStep, vkLoginComplete } = require('./vk-auth');
app.get('/', (req, res) => res.send('Hello World!'));
app.get('/login/vk', (req, res) => vKAuthFirstStep(res));
app.get('/login/vk/complete', vkLoginComplete);
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`));
Запускаем и тестируем.
Весь код доступен на githube.