С каждым днём влияние социальных сетей и сервисов только крепчает. Это означает, что нам, как веб разработчикам нужно это учитывать. Сегодня я расскажу и покажу, как создать аутентификацию ваших пользователей через социальную сеть ВКонтакте. Для этого мы не будем пользоваться какими-то сторонними библиотеками, а реализуем всё с нуля, собственными руками.
Думаю, многие ждали подобного урока, так что томить не буду. Начнём!
Заметка. Пример, созданный в данном уроке, предназначен для работы на локальном сервере.
Шаг 1. Регистрация нового приложения
Для начала нам необходимо создать новое приложение на сайте социальной сети ВКонтакте
В открывшейся форме введите название приложения; выберите тип “Веб-сайт”; В качестве адреса сайта введите путь к папке с проектом на вашем локальном сервере. В моём случае, это http://localhost/vk-auth. Базовый домен: localhost.
После нажатия на кнопку “Подключить сайт”, вам наверняка придётся ввести проверочный код, который придёт по смс. Если вы пройдёте проверку, то вам должна открыться следующая форма с настройками приложения.
API ВКонтакте C++(Qt) — 3 — Сохранение настроек, проверка токена
Сразу же хочу предупредить, что настоящие данные, относящиеся к моему приложению, я заменил на фиктивные, т.к. публикация таких значений как “Защищённый ключ” карается удалением вашего приложения или учётной записи в целом.
Из данной формы нам понадобятся такие данные, как `ID приложения`, `Защищённый ключ`, `Адрес сайта`. Запишем их в специальные переменные в файле index.php:
$client_id, ‘redirect_uri’ => $redirect_uri, ‘response_type’ => ‘code’ );
С помощью функции http_build_query, передав туда массив параметров, получим чередование ключей и значений, как в url адресе. Итак, генерируем ссылку и выводим на экран:
Также тут я воспользовался функцией urldecode. Если этого не сделать, то в сгенерированной ссылке могут появиться закодированные символы слешей, знаков двоеточия и так далее. Что-то вроде этого:
Если же мы пропустим данную строку через функцию urldecode, то получим:
Итак, ссылка для аутентификации у нас готова. Если мы сформировали все параметры правильным образом и получили верный url, то пройдя по ссылке, будем перенаправлены по адресу, указанному в настройках приложения (‘http://localhost/vk-auth’). Только теперь к этому адресу будет прикреплён специальный параметр code:
// Пример. В вашем случае код будет другой
http://localhost/vk-auth/?code=f30621b146115b3bad
Шаг 3. Получение токена
Начинать процедуру аутентификации мы можем тогда и только тогда, когда к нам пришёл параметр code. Он нам нужен для того, чтобы получить специальный токен доступа, с помощью которого, в дальнейшем, мы достанем информацию о пользователе.
В первую очередь, снова сформируем нужные нам параметры для этого запроса:
if (isset($_GET[‘code’])) < $params = array( ‘client_id’ =>$>clientId, ‘client_secret’ => $this->clientSecret, ‘code’ => $_GET[‘code’], ‘redirect_uri’ => $this->redirectUri ); >
vk api получение аксес токена, простой скрипт
Далее нам нужно отправить GET запрос на адрес https://oauth.vk.com/access_token, передав перечисленные параметры. В PHP выполнить GET запрос по какому-то адресу можно несколькими способами. Для данного урока я воспользуюсь функцией file_get_contents.
if (isset($_GET[‘code’])) < $params = array( ‘client_id’ =>$client_id, ‘client_secret’ => $client_secret, ‘code’ => $_GET[‘code’], ‘redirect_uri’ => $redirect_uri ); $token = json_decode(file_get_contents(‘https://oauth.vk.com/access_token’ . ‘?’ . urldecode(http_build_query($params))), true); >
В результате, при успешном выполнении запроса в переменную $token будет записан ответ от ВКонтакте в JSON формате. Данная строка содержит 3 параметра: access_token, который мы будем использовать в следующих запросах для извлечения информации о пользователе, expires_in — время жизни токена, user_id — id пользователя, который прошёл аутентификацию.
Для того чтобы мы далее могли работать с данными параметрами, декодируем JSON строку с помощью функции json_decode и помещаем данные в массив, передав в качестве второго аргумента true.
Шаг 4. Получение информации о пользователе
Итак, теперь когда у нас есть параметры access_token и user_id, мы можем сделать запрос к ВКонтакте API и получить информацию о пользователе. Для начала снова подготовим массив с параметрами, которые в последствии превратим в фрагмент url строки.
if (isset($_GET[‘code’])) < $params = array( ‘client_id’ =>$client_id, ‘client_secret’ => $client_secret, ‘code’ => $_GET[‘code’], ‘redirect_uri’ => $redirect_uri ); $token = json_decode(file_get_contents(‘https://oauth.vk.com/access_token’ . ‘?’ . urldecode(http_build_query($params))), true); if (isset($token[‘access_token’])) < $params = array( ‘uids’ =>$token[‘user_id’], ‘fields’ => ‘uid,first_name,last_name,screen_name,sex,bdate,photo_big’, ‘access_token’ => $token[‘access_token’] ); > >
В параметр uids записываем id пользователя; в fields перечисляем через запятую поля, которые хотим извлечь (uid — id пользователя, first_name — имя, last_name — фамилию, screen_name — имя отображаемое на страницах VK, sex — пол, bdate — дату рождения, photo_big — фотографию). Для доступа к большему количеству полей обратитесь к ВКонтакте API users.get. В качестве последнего параметра передаём ‘access_token’.
Для получения информации о пользователе сфомированные параметры нам нужно отправить GET запросом по адресу https://api.vk.com/method/users.get.
if (isset($_GET[‘code’])) < $params = array( ‘client_id’ =>$client_id, ‘client_secret’ => $client_secret, ‘code’ => $_GET[‘code’], ‘redirect_uri’ => $redirect_uri ); $token = json_decode(file_get_contents(‘https://oauth.vk.com/access_token’ . ‘?’ . urldecode(http_build_query($params))), true); if (isset($token[‘access_token’])) < $params = array( ‘uids’ =>$token[‘user_id’], ‘fields’ => ‘uid,first_name,last_name,screen_name,sex,bdate,photo_big’, ‘access_token’ => $token[‘access_token’] ); $userInfo = json_decode(file_get_contents(‘https://api.vk.com/method/users.get’ . ‘?’ . urldecode(http_build_query($params))), true); > >
В результате, если всё было сделано правильно, то получим JSON ответ следующего вида:
Снова преобразуем JSON ответ в массив и обратимся к нулевому элементу, хранящемуся в массиве, доступному по ключу response:
if (isset($_GET[‘code’])) < $result = false; $params = array( ‘client_id’ =>$client_id, ‘client_secret’ => $client_secret, ‘code’ => $_GET[‘code’], ‘redirect_uri’ => $redirect_uri ); $token = json_decode(file_get_contents(‘https://oauth.vk.com/access_token’ . ‘?’ . urldecode(http_build_query($params))), true); if (isset($token[‘access_token’])) < $params = array( ‘uids’ =>$token[‘user_id’], ‘fields’ => ‘uid,first_name,last_name,screen_name,sex,bdate,photo_big’, ‘access_token’ => $token[‘access_token’] ); $userInfo = json_decode(file_get_contents(‘https://api.vk.com/method/users.get’ . ‘?’ . urldecode(http_build_query($params))), true); if (isset($userInfo[‘response’][0][‘uid’])) < $userInfo = $userInfo[‘response’][0]; $result = true; >> >
Прошу обратить внимание, что в данном фрагменте, я добавил специальную переменную $result, равную изначально false сразу же после проверки наличия GET параметра code. Если нам удалось извлечь информацию о пользователе, то мы меняем значение этой переменной на true.
$client_id, ‘redirect_uri’ => $redirect_uri, ‘response_type’ => ‘code’ ); echo $link = ‘
Аутентификация через ВКонтакте
‘; if (isset($_GET[‘code’])) < $result = false; $params = array( ‘client_id’ =>$client_id, ‘client_secret’ => $client_secret, ‘code’ => $_GET[‘code’], ‘redirect_uri’ => $redirect_uri ); $token = json_decode(file_get_contents(‘https://oauth.vk.com/access_token’ . ‘?’ . urldecode(http_build_query($params))), true); if (isset($token[‘access_token’])) < $params = array( ‘uids’ =>$token[‘user_id’], ‘fields’ => ‘uid,first_name,last_name,screen_name,sex,bdate,photo_big’, ‘access_token’ => $token[‘access_token’] ); $userInfo = json_decode(file_get_contents(‘https://api.vk.com/method/users.get’ . ‘?’ . urldecode(http_build_query($params))), true); if (isset($userInfo[‘response’][0][‘uid’])) < $userInfo = $userInfo[‘response’][0]; $result = true; >> if ($result) < echo «Социальный ID пользователя: » . $userInfo[‘uid’] . ‘
‘; echo «Имя пользователя: » . $userInfo[‘first_name’] . ‘
‘; echo «Ссылка на профиль пользователя: » . $userInfo[‘screen_name’] . ‘
‘; echo «Пол пользователя: » . $userInfo[‘sex’] . ‘
‘; echo «День Рождения: » . $userInfo[‘bdate’] . ‘
‘; echo ‘‘; echo «
«; > > ?>
Шаг 5. Извлечение информации о пользователе
Теперь извлекать информацию о пользователе мы можем из массива, хранящегося в переменной $userInfo по ключам uid, first_name, last_name, screen_name, sex, bdate, photo_big.
if ($result) < echo «Социальный ID пользователя: » . $userInfo[‘uid’] . ‘
‘; echo «Имя пользователя: » . $userInfo[‘first_name’] . ‘
‘; echo «Ссылка на профиль пользователя: «. ‘http://vk.com/’ . $userInfo[‘screen_name’] . ‘
‘; echo «Пол пользователя: » . $userInfo[‘sex’] . ‘
‘; echo «День Рождения: » . $userInfo[‘bdate’] . ‘
‘; echo ‘‘; echo «
«; >
Шаг 6. Дело за вами
Теперь, когда у нас есть такая информация, как ID пользователя, в первую очередь, нам необходимо проверить его наличие в нашей базе данных. Если пользователя с таким ID не существует, то значит он авторизовался с нашего сайта впервые, и мы внесём его в базу. Если пользователь уже есть, можем проверить не изменились ли какие-то данные о нём, например, имя или ещё что-то. Если да, обновим запись.
После этого, всё что нам осталось сделать, так это создать сессию и поместить в неё информацию о нашем пользователе.
$_SESSION[‘user’] = $userInfo;
На странице выхода из системы просто удаляем сессию с помощью функции unset.
Итог
Вот мы и подошли к концу данного урока, и теперь в ваших руках есть решение, которого вы, возможно, долго ждали. Если вас интересует тема аутентификации через социальные сети, то пишите об этом в комментариях, и я с радостью расскажу и покажу, как работать с Одноклассниками, Google-ом, Facebook-ом и другими сервисами.
Источник: yadro.top
access_token has expired #225
The text was updated successfully, but these errors were encountered:
SanteR1 commented Apr 19, 2016
inyutin-maxim commented Apr 19, 2016
CaCTuCaTu4ECKuu commented Apr 19, 2016
Кстати, когда получает токен он возвращает expires, но если мне не изменяет память то в VkApi Aurhorize не возвращает его и я то ли не подумал то ли лень было, его надо бы запоминать.
Сейчас, по идее, нет такого поля, но первый запрос по истечению срока вернет ошибку TokenExpired и на нее можно забиндить RefreshToken.
А событие — вы уловили суть. Создаете делегат и чпок рефреш, единственное что либа не выполнить заново тот вызов, во время которого и выскочил ексепшн, тобишь этот момент нужно писать вручную 🙁
SanteR1 commented Apr 19, 2016
Просто если много методов, то придется в каждом try-catch добавлять RefreshToken. Не особо удобно конечно.
А никаким методом из vkapi не проверить «годность токена», например isAutorization, UserId?
И еще при получении токена, в каком виде возвращается expires. На его основании потом как то можно валидность проверять?
Источник: github.com
Авторизация API с помощью JWT токена в .NET 5.0
В этой статье мы узнаем, как создать и настроить аутентификацию JWT Bearer для авторизации API с помощью .NET 5.0. Есть много ресурсов, которые раскрывают тему «JWT Auth», но в этой статье мы будем сосредоточены на реализации пользовательской аутентификации JWT с кастомным промежуточным программным обеспечением и атрибутом авторизации.
JWT аутентификация
Необходимые инструменты:
Visual Studio 2019 — Можно загрузить здесь .Net 5.0 SDK — Можно загрузить здесь
План работы:
- Настройка проекта веб-API .NET 5.0.
- Настройка аутентификацию JWT
- Генерация токена JWT.
- Валидация токена JWT, используя кастомное промежуточное ПО и атрибут авторизации.
- Тестирование API с использованием Swagger.
Настройка проект .Net 5.0 Web API
Откройте Visual Studio, выберите «Создать новый проект» и нажмите кнопку «Далее».
Добавьте «Имя проекта» и «Имя решения» также выберите путь, чтобы сохранить проект в этом месте, нажмите «Далее».
Теперь выберите целевой фреймворк .NET 5.0, что мы получаем, как только мы устанавливаем SDK, а также получим еще один вариант для настройки поддержки OpenAPI по умолчанию с помощью этого флажка.
Настройка JWT-аутентификации
Чтобы настроить JWT (JSON веб-токен), у нас должен быть установлен пакет Nuget внутри проекта, поэтому давайте сначала добавим зависимости проекта.
Пакеты NuGet для установки
Внутри Visual Studio — нажмите на Tools -> Nuget Package Manager -> Manage Nuget packages for solution.
Установить через консоль.
Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -Version 5.0.7
Первый шаг — настроить аутентификацию JWT в нашем проекте. Для этого нам нужно зарегистрировать схему JWT в Swagger Service, используя метод Addauthentication .
Давайте определим службу SWARGER и закрепим за ней авторизацию по JWT.
#region Swagger Configuration services.AddSwaggerGen(swagger => < //This is to generate the Default UI of Swagger Documentation swagger.SwaggerDoc(«v1», new OpenApiInfo < Version = «v1», Title = «JWT Token Authentication API», Description = «ASP.NET Core 5.0 Web API» >); // To Enable authorization using Swagger (JWT) swagger.AddSecurityDefinition(«Bearer», new OpenApiSecurityScheme() < Name = «Authorization», Type = SecuritySchemeType.ApiKey, Scheme = «Bearer», BearerFormat = «JWT», In = ParameterLocation.Header, Description = «JWT Authorization header using the Bearer scheme. rnrn Enter ‘Bearer’ [space] and then your token in the text input below.rnrnExample: «Bearer 12345abcdef»», >); swagger.AddSecurityRequirement(new OpenApiSecurityRequirement < < new OpenApiSecurityScheme < Reference = new OpenApiReference < Type = ReferenceType.SecurityScheme, >>, new string[] <> > >); >); #endregion
Добавим службу для выполнения аутентификации, а также вызовем AddJWTBearer для конфигурации авторизации.
#region Authentication services.AddAuthentication(option => < option.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; option.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; >).AddJwtBearer(options => < options.TokenValidationParameters = new TokenValidationParameters < ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = false, ValidateIssuerSigningKey = true, ValidIssuer = Configuration[«Jwt:Issuer»], ValidAudience = Configuration[«Jwt:Audience»], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration[«Jwt:Key»])) //Configuration[«JwtToken:SecretKey»] >; >); #endregion
В приведенном выше примере мы указали параметры, которые необходимо учитывать для проверки токена.
- Проверка на сервере ( Validateissuer = true ), который генерирует токен.
- Проверка получателя токена, авторизован ли он для получения токена ( ValidateAudience = True )
- Проверка, не истек ли токен и валиден ли ключ подписания эмитента ( ValidateLifetime = True )
- Проверка подписи токена ( ValidateissuerSigningKey = True )
Мы должны указать значения для Audience , Issuer и Secret key в этом проекте, мы сохранили эти значения внутри файла appsettings.json .
appsettings.json
Генерация JWT токена
Давайте создадим контроллер с именем AuthController внутри папки controllers , и добавим метод Auth , который отвечает для проверку учетных данных входа и создадим токен на основе имени пользователя. Мы отметили этот метод с помощью атрибута AllowAnonymous для обхода аутентификации. Этот метод ожидает объект LoginModel для имени пользователя и пароля.
Мы создали директорию Services , в которой находится наша основная бизнес-логика, и мы используем внедрение зависимостей для использования этих служб в контроллере.
В демонстрационных целях я жестко запрограммировал значения внутри метода для проверки модели.
UserService.cs
public bool IsValidUserInformation(LoginModel model)
IUserService.cs
public interface IUserService
Добавьте эту службу в класс Startup в методе ConfigureServices .
services.AddTransient();
Внутри AuthController создадим приватный метод, известный как GenerateJWTToken , чтобы создать токен на основе эмитента, потребителя и секретного ключа, которые мы определили в файле appSettings.json .
using JWTAuth_Validation.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; using System; using System.ComponentModel.DataAnnotations; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using System.Text; namespace JWTAuth_Validation.Controllers < [Route(«api/[controller]»)] [ApiController] public class AuthController : ControllerBase < private readonly IConfiguration _configuration; private readonly IUserService _userService; public AuthController(IConfiguration configuration,IUserService userService) < _configuration = configuration; _userService = userService; >[AllowAnonymous] [HttpPost(nameof(Auth))] public IActionResult Auth([FromBody] LoginModel data) < bool isValid = _userService.IsValidUserInformation(data); if (isValid) < var tokenString = GenerateJwtToken(data.UserName); return Ok(new < Token = tokenString, Message = «Success» >); > return BadRequest(«Please pass the valid Username and Password»); > [Authorize(AuthenticationSchemes = Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerDefaults.AuthenticationScheme)] [HttpGet(nameof(GetResult))] public IActionResult GetResult() < return Ok(«API Validated»); >/// /// Generate JWT Token after successful login. /// /// /// private string GenerateJwtToken(string userName) < var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(_configuration[«Jwt:key»]); var tokenDescriptor = new SecurityTokenDescriptor < Subject = new ClaimsIdentity(new[] < new Claim(«id», userName) >), Expires = DateTime.UtcNow.AddHours(1), Issuer = _configuration[«Jwt:Issuer»], Audience = _configuration[«Jwt:Audience»], SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) >; var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); > > #region JsonProperties /// /// Json Properties /// public class LoginModel < [Required] public string UserName < get; set; >[Required] public string Password < get; set; >> #endregion >
Как только мы включили аутентификацию, я создал образец Get API, добавив атрибут авторизации, чтобы этот API выполнил проверку токена, передаваемого с помощью HTTP-запроса.
Если кто-то попытается получить доступ к этому API без надлежащего токена, он выдаст 401 Unauthorized Access в качестве ответа. Если мы хотим обойти аутентификацию для любого из наших существующих методов, мы можем пометить этот метод атрибутом AllowAnonymous .
Проверка JWT токена, используя middleware и атрибут Authorization
Ниже показано настраиваемое промежуточное ПО JWT, которое проверяет токен в заголовке запроса Authorization , если он существует. При успешной проверке промежуточное ПО извлекает этого связанного пользователя из базы данных и закрепляет его за своим контекстом. context.Items[«User»] делает текущую учетную запись доступной для любого другого кода, работающего в текущей области запроса, который мы будем использовать ниже в настраиваемом атрибуте авторизации.
Создайте папку с именем Middleware , в которой добавьте классы JWTMiddleware и AuthorizeAttribute .
JWTMiddleware.cs
using JWTAuth_Validation.Services; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; using System; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Text; using System.Threading.Tasks; namespace JWTAuth_Validation.Middleware < public class JWTMiddleware < private readonly RequestDelegate _next; private readonly IConfiguration _configuration; private readonly IUserService _userService; public JWTMiddleware(RequestDelegate next, IConfiguration configuration, IUserService userService) < _next = next; _configuration = configuration; _userService = userService; >public async Task Invoke(HttpContext context) < var token = context.Request.Headers[«Authorization»].FirstOrDefault()?.Split(» «).Last(); if (token != null) attachAccountToContext(context, token); await _next(context); >private void attachAccountToContext(HttpContext context, string token) < try < var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.ASCII.GetBytes(_configuration[«Jwt:Key»]); tokenHandler.ValidateToken(token, new TokenValidationParameters < ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = true, ValidateAudience = true, // set clockskew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later) ClockSkew = TimeSpan.Zero >, out SecurityToken validatedToken); var jwtToken = (JwtSecurityToken)validatedToken; var accountId = jwtToken.Claims.First(x => x.Type == «id»).Value; // attach account to context on successful jwt validation context.Items[«User»] = _userService.GetUserDetails(); > catch < // do nothing if jwt validation fails // account is not attached to context so request won’t have access to secure routes >> > >
AuthorizeAttribute.cs
using JWTAuth_Validation.Controllers; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using System; namespace JWTAuth_Validation.Middleware < [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] public class AuthorizeAttribute : Attribute, IAuthorizationFilter < public void OnAuthorization(AuthorizationFilterContext context) < var account = (LoginModel)context.HttpContext.Items[«User»]; if (account == null) < // not logged in context.Result = new JsonResult(new < message = «Unauthorized» >) < StatusCode = StatusCodes.Status401Unauthorized >; > > > >
Давайте внедрим это промежуточное ПО в класс Startup .
app.UseMiddleware();
Теперь каждый раз, когда кто то попадает в API с заголовком авторизации, промежуточное ПО сначала проверит токен и отправляет соответствующую информацию в ответ на запрос.
Тестирование API с помощью Swagger (OpenAPI)
Запустите приложение. Это приведет нас к странице Swagger Index со всей настроенной конфигурацией, которую мы сделали в проекте.
Давайте передадим действительные учетные данные Auth API, чтобы получить токен доступа.
Скопируйте токен и добавьте тот же токен в форме авторизации, а затем нажмите Authorize .
Теперь всё API авторизовано в Swagger. Давайте проверим API Get.
Заключение
JWT давно известен в веб-разработке. Это открытый стандарт, который позволяет безопасно и компактно передавать данные для авторизации в виде объекта JSON. В этой статье мы узнали, как создать и проверить JWT с помощью основного приложения ASP.NET.
Источник: forproger.ru