Progress28.ru

IT Новости
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Asp phpsessid carbonate btc

Безопасный способ обмена JWT в ASP.NET Core + SPA

Вступление

Идентификация по JWT (JSON Web Token) — это довольно единообразный, согласованный механизм авторизации и аутентификации между сервером и клиентами. Преимущества JWT в том, что он позволяет нам меньше управлять состоянием и хорошо масштабируется. Неудивительно, что авторизация и аутентификация с его помощью все чаще используется в современных веб-приложениях.

При разработке приложений с JWT часто возникает вопрос: где и как рекомендуется хранить токен? Если мы разрабатываем веб-приложение, у нас есть два наиболее распространенных варианта:

  • HTML5 Web Storage (localStorage or sessionStorage)
  • Cookies

Сравнивая эти способы, можно сказать, что они оба сохраняют значения в браузер клиента, оба довольно просты в использовании и представляют собой обычное хранилище пар ключ-значение. Разница заключается в среде хранения.

Web Storage (localStorage/sessionStorage) доступен через JavaScript в том же домене. Это означает, что любой JavaScript код в вашем приложении имеет доступ к Web Storage, и это порождает уязвимость к cross-site scripting (XSS) атакам. Как механизм хранения Web Storage не предоставляет никаких способов обезопасить свои данные во время хранения и обмена. Мы можем его использовать только для вспомогательных данных, которые хотим сохранить при обновлении (F5) или закрытии вкладки: состояние и номер страницы, фильтры итд.

Токены также могут передаваться через файлы cookie браузера. Файлы cookie, используемые с флагом httpOnly, не подвержены XSS. httpOnly — это флаг для доступа к чтению, записи и удалению cookies только на сервере. Они не будут доступны через JavaScript на клиенте, поэтому клиент не будет знать о токене, а авторизация будет полностью обрабатываться на стороне сервера.

Мы также можем установить secure флаг, чтобы гарантировать, что cookie передается только через HTTPS. Учитывая эти преимущества, мой выбор пал на cookies.

Эта статья описывает подход к реализации авторизации и аутентификации с помощью httpOnly secure cookies + JSON Web Token в ASP.NET Core Web Api в связке со SPA. Рассматривается вариант, при котором сервер и клиент находятся в разных origin.

Настройка локальной среды разработки

Для корректной настройки и отладки взаимоотношений клиента и сервера через HTTPS я настоятельно рекомендую сразу настроить локальную среду разработки так, чтобы и клиент, и сервер имели HTTPS-соединение.

Если этого не сделать сразу, а пытаться выстраивать взаимоотношения без HTTPS-соединения, то в дальнейшем всплывет великое множество мелочей, без которых не будут корректно работать secure cookies и дополнительные secure-policy в продакшене с HTTPS.

Я покажу пример настройки HTTPS на OS Windows 10, сервер — ASP.NET Core, SPA — React.

Настроить HTTPS в ASP.NET Core можно с помощью флага Configure for HTTPS при создании проекта или, если мы не сделали этого при создании, включить соответствующую опцию в Properties.

Чтобы настроить SPA, нужно модифицировать скрипт на «start», проставив ему значение «set HTTPS=true». Моя настройка выглядит следующим образом:

Настройку HTTPS для среды разработки на других окружениях советую смотреть на create-react-app.dev/docs/using-https-in-development

Настройка ASP.NET Core сервера

Настройка JWT

В данном случае подойдет самая обычная реализация JWT из документации или любой статьи, с дополнительной настройкой options.RequireHttpsMetadata = true; так как в нашей среде разработки используется HTTPS:

Настройка CORS-политики

Важно: CORS-policy должна содержать AllowCredentials() . Это нужно, чтобы получить запрос с XMLHttpRequest.withCredentials и отправить cookies обратно клиенту. Подробнее об этом будет написано далее. Остальные опции настраиваются в зависимости от нужд проекта.

Если сервер и клиент находятся на одном origin, то вся конфигурация ниже не нужна.

Настройка cookie-policy

Принудительно настраиваем cookie-policy на httpOnly и secure.

По возможности устанавливаем MinimumSameSitePolicy = SameSiteMode.Strict; — это повышает уровень безопасности файлов cookie для типов приложений, которые не полагаются на обработку cross-origin запросов.

Идея безопасного обмена токеном

Эта часть представляет собой концепцию. Мы собираемся сделать две вещи:

  1. Прокинуть токен в HTTP-запрос с использованием httpOnly и secure флагов.
  2. Получать и валидировать токены клиентских приложений из HTTP-запроса.

Для этого нам надо:

  • Записывать токен в httpOnly cookie при логине и удалять его оттуда при разлогине.
  • При наличии токена в cookies подставить токен в HTTP-заголовок каждого последующего запроса.
  • Если токена нет в cookies, то заголовок будет пустым, а запрос не будет авторизованным.

Middleware

Основная идея — это реализовать Custom Middleware для вставки токена во входящий HTTP-запрос. После авторизации пользователя мы сохраняем cookie под определенным ключом, например: «.AspNetCore.Application.Id». Я рекомендую задавать название, никак не связанное с авторизацией или токенами, — в этом случае cookie с токеном будут выглядеть как какая-то непримечательная системная константа AspNetCore приложения. Так выше шанс, что злоумышленник увидит много системных переменных и, не разобравшись, какой механизм авторизации используется, пойдет дальше. Конечно, если он не прочитает эту статью и не будет специально высматривать такую константу.

Далее нам нужно вставить этот токен во все последующие входящие HTTP-запросы. Для этого мы напишем несколько строк кода Middleware. Это не что иное, как HTTP-pipeline.

Мы можем вынести эту логику в отдельный Middleware-сервис, чтобы не засорять Startup.cs, идея от этого не изменится.

Для того чтобы записать значение в cookies, нам достаточно добавить следующую строку в логику авторизации:

С помощью наших cookie-policy эти cookie автоматически отправятся как httpOnly и secure. Не нужно переопределять их политику в cookie options.

В CookieOptions можно задать MaxAge, чтобы указать время жизни. Это полезно указывать вместе с JWT Lifetime при выпуске токена, чтобы cookie исчезала по истечении времени. Остальные свойства CookieOptions настраиваются в зависимости от требований проекта.

Для обеспечения большей безопасности советую добавить в Middleware следующие заголовки:

  • Заголовок X-Content-Type-Options используется для защиты от уязвимостей типа MIME sniffing. Эта уязвимость может возникнуть, когда сайт позволяет пользователям загружать контент, однако пользователь маскирует определенный тип файла как что-то другое. Это может дать злоумышленникам возможность выполнять cross-site scripting сценарии или компрометировать веб-сайт.
  • Все современные браузеры имеют встроенные возможности фильтрации XSS, которые пытаются поймать уязвимости XSS до того, как страница будет полностью отображена нам. По умолчанию они включены в браузере, но пользователь может оказаться хитрее и отключить их. Используя заголовок X-XSS-Protection, мы можем фактически сказать браузеру игнорировать то, что сделал пользователь, и применять встроенный фильтр.
  • X-Frame-Options сообщает браузеру, что если ваш сайт помещен внутри HTML-фрейма, то ничего не отображать. Это очень важно при попытке защитить себя от попыток clickjacking-взлома.
Читать еще:  Url decode php

Я описал далеко не все заголовки. Есть еще куча способов по достижению большей безопасности веб-приложения. Советую ориентироваться на чеклист по безопасности из ресурса securityheaders.com.

Настройка SPA клиента

При расположении клиента и сервера на разных origin требуется дополнительная настройка и на клиенте. Необходимо оборачивать каждый запрос использованием XMLHttpRequest.withCredentials.

Я обернул свои методы следующим образом:

Мы можем обернуть свой request config любым способом, главное, чтобы там был withCredentials = true.

Свойство XMLHttpRequest.withCredentials определяет, должны ли создаваться кросс-доменные запросы с использованием таких идентификационных данных, как cookie, авторизационные заголовки или TLS сертификаты.

Этот флаг также используется для определения, будут ли проигнорированы куки, переданные в ответе. XMLHttpRequest с другого домена не может установить cookie на свой собственный домен в случае, если перед созданием этого запроса флаг withCredentials не установлен в true.

Другими словами, если не указать этот атрибут, то наш cookie не сохранится браузером, т.е. мы не сможем обратно отправить cookie на сервер, а сервер не найдет желаемую cookie с JWT и не подпишет Bearer Token в нашем HTTP-pipeline.

Для чего все это нужно?

Выше я описал устойчивый к XSS способ обмена токенами. Пройдемся и посмотрим на результат реализованной функциональности.

Если зайти в Developer Tools, мы наблюдаем заветные флаги httpOnly и secure:

Проведем crush-test, попробуем вытащить куки из клиента:

Мы наблюдаем ‘ ‘, т.е. куки не доступны из пространства document, что делает невозможным их чтение с помощью скриптов.

Мы можем попробовать достать эти cookie с помощью дополнительных инструментов или расширений, но все перепробованные мной инструменты вызывали именно нативную реализацию из пространства document.

Asp phpsessid carbonate btc

GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.

php_btc_exchange / entity / Session.php /

No definitions found in this file.

class Session extends MainEntity
<
private $ id ;
private $ session_id ;
private $ user_id ;
public function getUserId ()
<
return $ this -> user_id ;
>
public function findBySessionId ( $ sessionId )
<
$ query = «SELECT id, session_id, user_id FROM `Session`
WHERE session_ ;» ;
$ result = self :: query ( $ query );
if ( isset ( $ result ))
<
$ this -> id = $ result [ ‘id’ ];
$ this -> session_id = $ result [ ‘session_id’ ];
$ this -> user_id = $ result [ ‘user_id’ ];
>
>
public function isSessionExistByUserId ( $ user_id )
<
$ query = «SELECT id FROM Session
WHERE user_ ;» ;
$ result = self :: query ( $ query );
if (! empty ( $ result ))
<
$ this -> id = $ result [ ‘id’ ];
return true ;
>
return false ;
>
public function isSessionExist ( $ clientIP )
<
$ session_id = self :: startSession ();
$ hash = Core :: calculateHash ( $ session_id . $ clientIP );
$ query = «SELECT * FROM `Session`
WHERE session_ ;» ;
$ result = self :: query ( $ query );
if (! empty ( $ result ))
<
$ this -> id = $ result [ ‘id’ ];
$ this -> user_id = $ result [ ‘user_id’ ];
$ this -> session_id = $ hash ;
return true ;
>
return false ;
>
public function delete ()
<
$ query = «DELETE FROM `Session`
WHERE >id’;» ;
self :: execute ( $ query );
>
private function insert ()
<
$ query = «INSERT INTO `Session` (session_id, user_id)
VALUES (‘$this->session_id’, ‘$this->user_id’);» ;
self :: execute ( $ query );
>
public function create ( $ userID , $ clientIP )
<
$ session_id = self :: startSession ();
$ this -> session_id = Core :: calculateHash ( $ session_id . $ clientIP );
$ this -> user_id = $ userID ;
$ this -> insert ();
>
static public function startSession ()
<
if (! session_id ())
session_start ();
return session_id ();
>
static public function getSessionVariable ( $ key )
<
self :: startSession ();
if ( isset ( $ _SESSION [ $ key ]))
return $ _SESSION [ $ key ];
return null ;
>
static public function setSessionVariable ( $ key , $ value )
<
self :: startSession ();
$ _SESSION [ $ key ] = $ value ;
>
static public function unsetSessionVariable ( $ key )
<
self :: startSession ();
unset( $ _SESSION [ $ key ]);
>
>
  • © 2020 GitHub, Inc.
  • Terms
  • Privacy
  • Security
  • Status
  • Help

You can’t perform that action at this time.

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.

Build Your Own Bitcoin API using Node.js and Bitcoin Core

In this tutorial we will build an API using Node.js and Express that retrieves data from Bitcoin Core. This tutorial is meant to be a starter for anyone looking to create Bitcoin applications with Javascript. You can use this API as a bitcoin backend to build web applications such as a block explorer or wallet.

Bitcoin Core is the primary software implementation of the Bitcoin protocol. It is basically a software program that allows you to mine, store, and transact in bitcoin. It also automatically validates other people’s transactions and lets you query all sorts of blockchain data.

Bitcoin has a RPC (remote procedure protocol) API with dozens of commands which can be found here. These commands include everything you need to interact with the Bitcoin client. It is possible to use the RPC API to create addresses and send transactions, however in this tutorial we will only be using commands which query data.

Before we can use this API, you will need to run Bitcoin Core. If you don’t already have Bitcoin Core installed on your computer, you can download it here. The blockchain size is over 225gb and always increasing, so make sure you have enough hard drive space and internet bandwidth to run the software (see Costs and Warnings). Bitcoin can take several days to sync to the current blockchain, so it is a good idea to setup the node in advance in order to test out the API.

Читать еще:  Division by zero php

Additionally you will need to install Node.js which can be found here.

The full code for this tutorial and API can be found on Github. If you clone the repository, make sure to create a .env file and add your RPC login info (explained below)

Project Setup

Once you have bitcoin installed and synced, create a folder for your application and navigate to it.

Then initialize a new node application by entering

This will create a package.json file, which we can specify a start script and other details for our application.

Add the line «server»: «nodemon server.js» into the scripts object. You can replace the default «test» command, which we won’t be using.

Your package.json file should look similar to:

Next, lets build out our project structure and files. In the project directory add a server.js file for our server and .env file to store our bitcoin login. Next, add a routes folder with api.js file for our endpoints. The following commands, input separately, will do this in the command line:

Next we can install the additional javascript packages we’ll be using. Packages (or dependencies) are 3rd party javascript code we will utilize in our application. Install the needed dependencies with the following two commands

body-parser — converts our HTTP responses to JSON to easily consume data
dotenv — reads our bitcoin login info from the .env file
express — our routing framework, lets us specify method endpoints
request — allows us to send HTTP requests to the bitcoin client
nodemon — restarts the server when changes are detected

Setting up a server

We will need a server that hosts our API endpoints in the browser. To do this, add the following code to server.js

In the first 3 lines we are setting our dependencies and endpoint location to be javascript variables.

Next we initialize express (our routing framework) to the app variable. With app.use() we can setup our body parser (formats data response) and declare where our API endpoints will live.

After that we will set a port variable to be 4444 or whatever digits you choose. This will be the location in the browser where you can view the returned blockchain data. At the end of this file, we initialize our server on the port specified and log a success message.

This script will run once when we start our server, then stay running until the process is terminated. Nodemon will allow us to save changes to our application without having the restart the server. Before we start the server, let’s also setup our Bitcoin client login and API.

Configuring Login Information

In order to use the Bitcoin RPC API, a username and password are required in the Bitcoin Core configuration file. This will allow us to connect with the node remotely using HTTP. You can add these values to the bitcoin.conf file by selecting

Settings -> Options. -> Open Configuration File

inside of Bitcoin Core, which will open a text file. Add the following lines to this file:

then save in the text editor, and restart Bitcoin Core.

Note: This login info will allow anyone with access to your node to run RPC commands including sending transactions. Be alert when setting up APIs connected to wallets containing Bitcoin, and don’t post this information anywhere on the web. For this example, I will use a dummy login, though you should choose your own username and password.

Now, back in our project’s .env file, we can add the same information to our API. The naming convention will be slightly different, however the login will be the same as in bitcoin.conf

Lastly and optionally, if you plan to store this code remotely, create a .gitignore file in the root project folder. Add .env to this file, so that you don’t accidentally commit your node’s RPC login.

Bitcoin RPC Routes

In our server.js file we specified that express should look for our endpoints in /routes/api.js . These endpoints will hold the various bitcoin RPC methods that we can use to interact with the software.

To setup this file, add the following code to api.js:

Here we are again initializing an express router, request module, and environmental variables. The headers variable will be the same in each request so we can include it at the top. The line that begins with router.get(«/test», . ) is our test route, which we will soon be able to view.

Start the application by entering the command:

If the server has started correctly, in your console you should see

Server running on port 4444

Now open your browser and navigate to:

you should get the message “backend works” as a response.

We will be setting up 12 more routes in this application, each which correspond to a Bitcoin RPC command. These methods can be used in the Bitcoin Core console (found under Window -> Console in Bitcoin Core), as well as in our Node.js application.

Читать еще:  Configuration php настройка

Basic Routes

The first 8 routes we will use do not require an input argument. They include:

These 8 methods will return to us some details about the current state of the blockchain, mempool, and our node’s network connections. Each method will be accessed in the same way, and return an object with our requested data.

To setup our first route, replace the comment

// . routes will go here

with the following code:

Here we are telling the express router to listen for when a user hits the endpoint /api/getblockcount . The dataString and options variables include input parameters such as the name of the method we are calling and the url of our bitcoin node (including our login). If we are running both the server and bitcoin node, in the browser at localhost:4444/api/getblockcount we should see the response

In this response, the value 588608 is the current number of blocks in the blockchain. Each response will have an object containing the requested data in the result property.

To set up the other 7 methods

simply reuse the getblockcount code above for each method. In each endpoint there will be 2 instances of the method name, one to specify the endpoint address such as /getblockcount , and the other as a value in the dataString variable such as «method»: «getblockcount» . Replace both of these variables for each of the 7 methods above and you will have an API with 8 endpoints to Bitcoin RPC commands!

(Alternatively you can just copy all 12 endpoints from here)

Take some time to explore the various responses from these basic commands. getblockchaininfo , getmininginfo , and getpeerinfo are loaded with useful information that you can use to build interesting applications.

Single Parameter Methods

In this tutorial we will also be querying blockchain data using 4 methods which require 1 input argument each. These methods are listed below with a space between their name and the name of the input parameter.

These 4 methods allow us to lookup blocks and transactions.

Each block on the Bitcoin blockchain has a unique index and hash value. The block’s hash is required to get data about the block. This hash can be retrieved with the getblockhash method, passing in an index of the specified block. Once the block’s hash is returned, we can find the block info with the getblock command, passing in the block’s hash .

To include this functionality in our API we can add the following methods for block retrieval

Note I included both endpoints here as the getblockhash method accepts a number instead of a string.

With each of these methods, we will also need to pass in an input parameter. For example, to find a blockhash with the getblockhash command, visit:

in your browser. The block index here is passed in by adding a / after the method endpoint and before the input parameter.

You can find this block’s transaction data by using the returned block hash as an argument to a getblock call.

Now, with our API we are capable of finding the transactions in the most recent block by stringing together the getblockcount , getblockhash , and getblock commands together. We can also find the transactions in any block that we have the index or hash for.

Transaction Methods

For our transaction methods we will need a Bitcoin node that is indexing transactions in order to access the entire blockchain. To index the transactions on your node, you will need to add the following line to the bitcoin.conf file

save this file, then restart Bitcoin Core. Indexing the entire blockchain will take some time as well as additional storage on your harddrive. It is recommended to index the blockchain overnight or while you are away from your computer, as it can take several to many hours.

Each transaction in the bitcoin blockchain has a unique >getrawtransaction method to return the hex encoded transaction data. The decoderawtransaction method can be used with this hex data as an argument to reveal information about that transaction.

Add the following transaction endpoints to your api.js file

Every Bitcoin RPC command can be added as an endpoint in this API to make fully functional Bitcoin applications.

With these 12 methods we have setup a communication with our Bitcoin node that will allow us to build all sorts of applications.

Next Steps (React)

There are a multitude of libraries and frameworks you can use to build fully functional web applications on top of Bitcoin. As a starting point, these are some basic steps to build a React application which is able to talk with our API.

To setup a new React application, enter the following command in the root of your project folder

Next, change directories into your frontend folder and add the axios package for API requests by entering

Additionally, you will need to add a proxy to your frontend package.json file for your API requests.

From here we simply need to setup our React application to store the API data in state. To test out the getblockchaininfo , getmininginfo , and getpeerinfo methods update your App.js file to the following:

Let’s see our basic full stack application in action by starting our React frontend with the command:

Ссылка на основную публикацию
Adblock
detector