{imgicourl}{zamok}
Другие записи за это число:
2022/12/07_qdrinx - Хроники полураспада
<< предыдущая заметкаследующая заметка >>
07 декабря 2022
Логин на сайте по ключу NFC, банковской или транспортной карте

Мои читатели постоянно жалуются на проблемы с логином на сайте. Там действительно постоянные проблемы, часть из которых связана с глючащими сторонними сервисами, через которые можно логиниться Гуглем, Фейсбуком и прочей ерундой. Родная часть авторизации сайта, которую писал я сам (логин-пароль), она второе десятилетие работает без проблем, вот только мало кто использует логин-пароль. И потом не могут вспомнить. И емайл давно сменили. Тем не менее, я что-то время от времени дорабатываю и чиню. А сегодня сделал логин по банковской карточке. Шучу. В смысле — не шучу. В смысле, не по банковской карточке. Вообще по любой метке NFC. И банковская не исключение.

Расскажу по порядку. Cовременные телефоны умеют читать поднесенные к ним метки NFC. А некоторые браузеры — в частности, Android Chrome — позволяют делать это скриптом прямо со страниц сайта. Сразу скажу, что твой браузер — хрен знает, что за зверь. Скорее всего, ты читаешь пост не на моем сайте, а в какой-нибудь соцсети, RSS или иной помойке, куда копию текста занес робот. Тогда можно дальше не читать, речь про мой сайт..

Меткой NFC может быть что угодно — большинство ключей от домофона или офиса, любая транспортная карта или банковская бесконтактная. Некоторые карты в принципе тоже NFC, но имеют другой стандарт, и там не читается даже серийник. Например, водительские права и еще пару экзотических карт мне прочесть не удалось — связь по NFC срабатывает, но в ответ пишет, что формат неизвестен. Но у большинства карт телефон может прочесть уникальный номер чипа (типа A0:CD:48:1E:DF) и использовать как простой уникальный ключ для логина.

Как добавить ключ NFC к своему действующему аккаунту?

Видим кружочек в правой верхней части страницы и жмем на него (стараясь не попасть в квадратик письма, иначе откроется личная почта, а не личная карточка). Когда открылась личная карточка, видим в ней посерединке новую надпись с кнопкой: «Ключ NFC: [Add]» Жмем «Add», и если все хорошо (если не вылетит сообщение, что браузер не поддерживает NFC), то экран потемнеет и в центре будет крутиться каруселька. Это значит, что у вас есть долгие 10 секунд, чтобы поднести к телефону какую-нибудь карту. Если прочитать NFC удалось, телефон напишет «Saved!», и отныне вы всегда сможете этой картой залогиниться на моем сайте (пока не удалите ее в той же личной карточке при помощи красной кнопки).

Теперь как залогиниться ключом NFC?

Из той же личной карточки жмем вверху кнопку «залогиниться» (есть и прямая ссылка: https://lleo.me/dnevnik/login), в открывшемся окне жмем кнопку «Scan NFC». Экран темнеет, каруселька крутится, подносим карту — ура, сайт нас узнал.

Как это работает физически?

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

Недавно я узнал, что в некоторых мобильных браузерах уже есть поддержка NDEFReader — работы с NFC-картами. На уровне JS-запроса можно просканировать ID почти любой NFC-карты, а для незащищенных карт еще почитать блоки данных и даже позаписывать информацию в ячейки. Кому интересно — гуглим «JS NDEFReader», а ниже я покидал примеров.

[технические подробности]
Проверка, поддерживает ли браузер технологию:

if('NDEFReader' in window) alert('поддерживает');

Чтение карты:

const NFC_scan = async (m) => {

 сonst ndef = new NDEFReader();

 ndef.onreadingerror = (ev) => {
   alert('Error! Cannot read the NFC tag!');
 };

 ndef.onreading = (ev) => {
   const R = ev.message.records;
   alert('Serial Number: '+ev.serialNumber+' Records: '+R.length);
   for(var i=0;i<R.length;i++) { var e=R[i];
     alert(i+'. recordType='+e.recordType+'+(e.mediaType?' MIME type='+e.mediaType:'');

     // данные data в загадочной кодировке, текст вытягивается так
     var enc = e.encoding; if(!enc) enc='utf-8';
     const decoder = new TextDecoder(enc);
     var text = decoder.decode(e.data);
     alert('text='+text);
   }
 };

 await ndef.scan();
};

Разумеется, здесь и далее внутри у подобных процедур рекомендуется содержимое заворачивать в try{}catch(){} дабы избежать возможных ошибок.

Типы данных богаты. recordType бывает таким:

"text" — просто текст на любом языке)

"mime" — тогда подробности о типе данных записаны в mediaType, например "application/json"

"url" — ссылка, которая обычно откроется в браузере, если просто подносить телефон

"...:pkg" — приложение, которое откроется при поднесении, например, можно записать такую ячейку, чтобы сразу открылись контакты: recordType: "android.com:pkg",data: encoder.encode("com.android.contacts")

"...:act"  — тоже похожая фигня, уже не помню.

И всё это точно так же можно в карту записывать (разумеется, в тэг, не закрытый от записи, и желательно с большим объемом памяти, у меня такой был для экспериментов):

const NFC_write = async (m) => {

 сonst ndef = new NDEFReader();

 // await ndef.write('Я пишу на Расте — потолок покрасьте!');

 const encoder = new TextEncoder();
 await ndef.write({
  records: [

    {
      recordType: 'mime',
      mediaType: 'application/json',
      data: encoder.encode(JSON.stringify({ name: 'Leo Kaganov', title: 'Writer' }))
    },

    {
      recordType: 'mime',
      mediaType: 'application/json',
      data: encoder.encode(JSON.stringify({ name: 'Иван Говнов', title: 'Engineer' }))
    },

    {
      recordType: 'url',
      data: 'https://natribu.org'
    },

    {
      recordType: 'android.com:pkg',
      data: encoder.encode('com.android.contacts')
    },

    {
      recordType: 'mime',
      mediaType: 'image/webp',
      data: await (await fetch('/image_file.webp')).arrayBuffer()
    },

    {
      recordType: 'mime',
      mediaType: 'audio/mp3',
      data: await (await fetch('/audio_file.mp3')).arrayBuffer()
    },
  ]
});

Кстати, из-за параноидальной политики браузера я не могу пока эту систему поставить на Биноник: одно из требований — работа в главном окне if(window.top===window). А в многопользовательском режиме движка политика безопасности у меня построена ровно наоборот: в главном окне ты можешь делать что хочешь (владельцам аккаунтов разрешен JS), зато все авторизационные и секретные действия выполняются в специальном защищенном поддомене. Но со временем я подумаю, как сделать и в многопользовательском движке NFC-логин безопасным.

Иными словами, в тестовую карту я пробовал даже писать крохотные файлы, но без особого успеха — памяти не хватает. Хотя какую-то картинку 30x30 пикселей мне залить удалось. Но зачем, если можно просто ссылку? В любом случае я пока не придумал практического применения записи на карту. Но вот чтение ID карты — штука, которая позволяет использовать ее как ключ. Так что добро пожаловать протестировать. На данный момент уже протестировали 7, считая меня :)

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

Однако если вас как-то напряг мой сегодняшний рассказ о возможностях браузера, если вас напугала мысль, что в браузере вашего мобильника, пока он болтается в кармане, может случайно открыться какой-то левый сайт, потом случайно нажмётся кнопка «разрешить NFC», и этот сайт сможет прочесть тэг лежащей в том же кармане банковской карты... то вы, разумеется, можете применить шапочку из фольги. То есть буквально: полностью обернуть свои банковские карты фольгой. Я попробовал — через фольгу не читает.

<< предыдущая заметка следующая заметка >>
пожаловаться на эту публикацию администрации портала
архив понравившихся мне ссылок

Комментарии к этой заметке скрываются - они будут видны только вам и мне.

Оставить комментарий