Обзор

Мой первый клиентский проект в Hack Reactor был с Moxe Health, компанией Rock Health, которая стандартизирует электронные медицинские карты тысяч больниц по всей стране. Moxe заключила с нами контракт на создание полезного продукта, который также продемонстрировал их API. Я вместе с моим товарищем по команде Яном Лайонсом (законным разработчиком программного обеспечения, который пишет несколько замечательных сообщений в блогах) создал калькулятор лечения высокого кровяного давления, который помогает врачам визуализировать ход лечения пациента и сообщать наиболее эффективный и доступный план лечения для их пациентов. пациенты.

Проверьте приложение здесь и поэкспериментируйте. Или используйте его на следующем приеме у врача! (отказ от ответственности: это приложение никоим образом не предназначено для использования в качестве диагностического инструмента или замены рекомендации врача).

В этом проекте с полным стеком было так много забавных моментов, от внешнего интерфейса Angular до внутреннего интерфейса MySQL, поэтому я вынужден коснуться лишь нескольких. Я собираюсь обсудить:

  • Пользовательский опыт
  • Структуры файлов и папок
  • Быстрая и грязная авторизация

Пользовательский опыт

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

Встречи клиницистов были плодотворными. Например, когда мы показали нашу первую демонстрацию врачу, он заметил, что проблема, с которой он столкнулся при лечении артериального давления, состоит в том, чтобы найти наиболее доступное лекарство для пациента. Иногда он прописывает лекарство, которое, по его мнению, будет довольно дешевым для пациента, а на следующий день ему звонят из аптеки и сообщают, что страховка пациента не покрывает это лекарство. Это раздражает и отнимает время врача и пациента.

Эта проблема была явной болевой точкой для врачей. В ответ мы подключили наш механизм рекомендаций по лекарствам к API GoodRx. Теперь врачи получают наличную цену за каждое рекомендованное лекарство, поэтому они могут легко включить цену в свой процесс принятия решений при выборе рекомендации для своего пациента. Было полезно получить представление о повседневной жизни врачей и использовать эти знания для создания продукта, который врачи действительно будут использовать.

Структура файлов и папок

Сначала мы организовали наше приложение довольно просто (исключая другие стандартные документы и папки, такие как package.json и bower_components/):

app //frontend code 
lib //algorithm functions 
server.js //initialize express server connection 
db-config.js //initialize MSSQL database connection 
emails.js //functions providing smtp transport functionality 
encrypt.js //functions to create email hash 
route-handler.js //express routes ms-schema.sql //schema for MySQL database

Эта структура работала для большей части проекта, но она беспорядочна. Для server.js имело смысл находиться в корневом каталоге, но не для служебных файлов, таких как emails.js и encrypt.js. Мы также не инкапсулировали функциональность так хорошо, как могли бы. Например, route-handler.js содержал логику запросов к базе данных внутри определенных маршрутов.

Мы реорганизовали наш код для лучшей организации и инкапсуляции приложений. Мы использовали mean.io в качестве руководства, потому что, кроме нашего бэкэнда MySQL, наше приложение было во многом приложением MEAN:

app 
server 
config 
production.js
db-config.js
models
ms-schema.sql 
db-helpers.js 
routes 
route-handler.js 
util 
email.js 
encrypt.js 
saml.js 
server.js

Теперь разделение интересов стало более четким. Вся логика запросов к базе данных перенесена в db-helpers.js. Различные служебные функции сгруппированы в отдельной папке util. Папка конфигурации дает возможность добавлять среды разработки и тестирования, а также настраивать базу данных. Наконец, размещение route-handler.js в папке маршрутов делает наше приложение более легко расширяемым, если мы хотим добавить больше маршрутов.

Быстрая и грязная аутентификация

Мы использовали криптографический хэш для создания уникальной ссылки из введенного пользователем адреса электронной почты (для любых посетителей веб-сайта нашего приложения) или идентификатора пациента (для пользователей в системе Moxe), что позволило им получить доступ к ранее введенным данным и добавить новые данные при последующих посещениях. по этой ссылке, без необходимости вводить пароль. Если вы хотите быстро создать приложение и использовать большинство преимуществ аутентификации, не мучаясь при настройке аутентификации, я настоятельно рекомендую создавать уникальные ссылки.

Обратите внимание, что криптографические хэши отличаются от шифрования. Сначала я был смущен этим. Генерация криптографического хэша — это вычисление статистически уникального отпечатка пальца для некоторого контента C, который не может быть декодирован для получения C, потому что это слишком затратно с вычислительной точки зрения. C может быть открытым текстом или зашифрованным текстом.

Криптографические хэши также можно использовать для обнаружения фальсификации данных, что так же важно, как и предотвращение фальсификации. Например, предположим, что C является значением в таблице MySQL. Сначала я хэширую:

C = хеш (мое значение)

& сохранить C в другом столбце:

моя таблица (моё значение, C)

Некоторое время спустя я пересчитываю хэш:

C’ = хеш (мое значение)

Если C' == C, myValue НЕ был изменен. Точно так же хэш можно использовать для обнаружения ошибок. Предположим, что сообщение отправлено по зашумленному каналу. Сравнение хэшей подтверждает, что сообщение прибыло целым.

Шифрование, в отличие от хеширования, представляет собой кодирование сообщения, поэтому его нельзя расшифровать без ключа. В отличие от вывода хеш-функции, вывод шифрования можно расшифровать с помощью расшифровки (ключа).

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

Следующий код находится в нашем файле encrypt.js и демонстрирует один из способов создания хэша:

/* The crypto node module offers a way of encapsulating secure credentials to be used as part of a secure HTTPS net or http connection. */ 
var crypto = require('crypto'); 
exports.makeEmailHash = function(userEmail) { 
/* we pass the following random string into the hashing function and append the result to the final hash, making the hash more complex and harder for an attacker to decrypt. Such a string is called a salt. Salts should be more complex than the following (we ran out of time do do this), such as the date of the server request concatenated with a randomly generated number. */ 
var salt = 'qTg21o76o9uhas;dnals+2KvN4qPJLFvy7qP6P'; //create an instance of class 'Hash' using the 'sha256' algorithm 
var hash = crypto.createHash('sha256'); //append the content to be hashed with the value of userEmail hash.update(userEmail); 
//append the content to be hashed with the value of salt hash.update(salt); 
/* Calculate the digest of all of the passed data to be hashed. In other words, generate the hash. Note that after invoking .digest(), the instance of hash cannot be used again. */ 
var safeHash = makeUrlSafe(hash.digest('base64')); console.log(safeHash); 
return safeHash;
/* Escape all characters that will cause unexpected requests to the server. For example, without the following function, all '&'s in the hash we generate will be replaced with '%20' when the hash is evaluated as a query string in a URI. */ 
var makeUrlSafe = function(string) { 
    string = replaceAll('+', "_", string); 
    string = replaceAll('/', "_", string); 
    return encodeURIComponent(string); 
};

Как все это вписывается в наше приложение? В route-handler.js мы генерируем хэш электронной почты, передавая идентификатор/электронную почту пациента в функцию makeUserHash:

var emailHashString = encrypt.makeEmailHash(ptId);

Затем мы вызываем другую функцию, которая добавляет хэш к URL-адресу в качестве значения переменной запроса uid и отправляет URL-адрес пользователю по электронной почте с помощью Nodemailer:

email.sendNewUserMail (получатель сообщения, emailHashString);

Вывод

В целом, из этого проекта было извлечено несколько полезных уроков о том, как включить отзывы конечных пользователей в полезные функции, структурировать приложение таким образом, чтобы оно было масштабируемым и инкапсулированным, и как генерировать зашифрованные хэши в качестве надежной замены аутентификации. Мне понравилось работать с Moxe Health, и я не могу дождаться новых проектов, подобных этому!

Первоначально опубликовано на www.shanemkeller.com, май 2014 г.