This article in progress...
В этой статье я зафиксирую для себя некоторые соображения о том, как дешевыми средствами организовать авторизацию по QR. Эта статья не претендует на абсолютную истину в надежности своего подхода. Просто мысли.
See also https://www.npmjs.com/package/qr-code-styling, TRY THIS
See also: How to create a QR code in ExpressJS
pravosleva.pro/express-helper/qr/swagger/
Варианты авторизации по QR
v1
- POST
/login
При успешной авторизации, создаём QR код с ссылкой и возможность перейти этой по ссылке успешно N раз.
Response:
{
...data,
qr,
// содержащий ссылку на /auth/go-target с параметрами:
// - logged_req_id
// - hash
}
- static page
/auth/go-target? logged_req_id=<STRING>& hash=<STRING>
Если клиент перешёл по ссылке с указанными параметрами и лимит аутентификации на доп устройствах не исчерпан, проверим ему на слово и авторизуем (NOTE: дыра в безопасности детектед!), актуализируя счётчик. Иначе варианты:
- ☐ 1) чистим куку и отвечаем 500
- ☐ 2) или переводим на err page?
- ✔ 3) или чистим куку и редиректим и на авторизацию с хэшом (если найдем хэш по logged_req_id (id успешного запроса /login), если нет - можно 500; ПОПРАВКА: hash и logged_req_id в параметрах этого запроса - 500-я будет в случаях: 3.1) невалидного хэша либо logged_req_id
Additional cookie
urgent_auth_service_msg cookie for 15 seconds (will be read on client for UI notification) httpOnly: false
OLD [2021-03-26]
🧨 Express minimalism
Simplest middleware.
import { Response as IResponse } from 'express'
import { ICustomRequest } from '~/utils/interfaces'
import QRCode from 'qrcode'
import { promisify } from 'es6-promisify'
const genDataUrl: (payload: string) => Promise<string> = promisify(QRCode.toDataURL.bind(QRCode))
export const tstGenerate = async (req: ICustomRequest, res: IResponse) => {
const { payload } = req.query
if (!payload) {
return res
.status(401)
.json({ ok: false, message: 'Missing required parameter: "payload"' })
}
const dataUrl = await genDataUrl(String(payload))
return res.status(200).json({
ok: true,
src: dataUrl,
})
}