Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Google Authenticator with NodeJS
Search
Philipp Dunkel
March 14, 2014
Programming
0
270
Google Authenticator with NodeJS
Mini-Talk at the first Vienn-NodeJS-Meetup
Philipp Dunkel
March 14, 2014
Tweet
Share
Other Decks in Programming
See All in Programming
MUSUBIXとは
nahisaho
0
130
MDN Web Docs に日本語翻訳でコントリビュート
ohmori_yusuke
0
650
CSC307 Lecture 04
javiergs
PRO
0
660
AI & Enginnering
codelynx
0
110
AWS re:Invent 2025参加 直前 Seattle-Tacoma Airport(SEA)におけるハードウェア紛失インシデントLT
tetutetu214
2
110
20260127_試行錯誤の結晶を1冊に。著者が解説 先輩データサイエンティストからの指南書 / author's_commentary_ds_instructions_guide
nash_efp
1
940
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
540
ThorVG Viewer In VS Code
nors
0
770
360° Signals in Angular: Signal Forms with SignalStore & Resources @ngLondon 01/2026
manfredsteyer
PRO
0
120
生成AIを使ったコードレビューで定性的に品質カバー
chiilog
1
260
AI によるインシデント初動調査の自動化を行う AI インシデントコマンダーを作った話
azukiazusa1
1
710
Unicodeどうしてる? PHPから見たUnicode対応と他言語での対応についてのお伺い
youkidearitai
PRO
1
2.5k
Featured
See All Featured
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.1k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.4k
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
640
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.1k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
79
Discover your Explorer Soul
emna__ayadi
2
1.1k
Balancing Empowerment & Direction
lara
5
880
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
64
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
450
From π to Pie charts
rasagy
0
120
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
0
200
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Transcript
GOOGLE-AUTHENTICATOR WITH NODEJS PHILIPP DUNKEL PIPOBSCURE
PROTOCOL • T imebased • O ne • T ime
• P assword RFC 6238 - http://tools.ietf.org/html/rfc6238
PRO - CON/CAVEATS • Variable / Changing • Second Factor
• Standardised • Added Security • Shared Secret • Raw Secret Stored !
GOOGLE AUTHENTICATOR - IN THE WILD • Amazon Web Services
• Asia Nexgen • Atomic-Trade.com • App.net • Bitstamp • Bitcoin.de • Blockchain.info • BTC-e.com • CaVirtEx.com • Cex.io • CipherGraph Networks • Coinbase • Dashlane • DigitalOcean • Dreamhost • Dropbox • Drupal • Evernote • Eclipse Mining Consortium • Facebook • Gaia Online • Gandi.net • GitHub • Google Apps • Google Mail • HootSuite • Joomla • LastPass • Linode • LinOTP • LocalBitcoins • Linux • Microsoft account • Mt. Gox • Net4Game • Okcoin • Salesforce.com • Synology • SupportPoint • TACACS.net • Teamviewer • timetotrade • WordPress • Xat • XenForo ! !
GOOGLE AUTHENTICATOR APP
MODULES - OTP & QRPNG
CREATE A SECRET var OTP = require(‘otp’); function createUser(request, reply)
{ var otp = OTP({ name: request.params.username + '@demo' }); var filename = __dirname + '/data/' + request.params.username + ‘.json’; var content = JSON.stringify(otp, undefined, ' ‘); fs.writeFile(filename, content, function(err) { if (err) return reply(err); reply(otp.totpURL); }); }
TOTP - INFORMATION { "class": "OTP{@phidelta}", "name": "pipobscure@demo", "keySize": 32,
"codeLength": 6, “secret": “INJCM5ZXGEYW2QJJGN5TEW25LNAC6NLUFZYWK2CWIE2U2S3MIZIQ“, "epoch": 0, "timeSlice": 30 } otpauth://totp/pipobscure@demo?secret=INJCM5ZXGEYW2QJJGN5TEW25LNAC6NLUFZYWK2CWIE2U2S3MIZIQ
CREATE A QR-CODE otpauth://totp/pipobscure@demo?secret=INJCM5ZXGEYW2QJJGN5TEW25LNAC6NLUFZYWK2CWIE2U2S3MIZIQ var QR = require(‘qrpng’); function fetchQRCode(request,
reply) { var url = request.query.url; var scale = request.query.scale || 4; QR(url, scale, function(err, png) { if (err) return reply(err); reply(png).type('image/png'); }); }
VALIDATE A CODE function verifyCode(request, reply) { var filename =
__dirname + '/data/' + request.params.username + ‘.json'; fs.readFile(, 'utf-8', function(err, data) { if (err) return reply(err); var otp = JSON.parse(data, OTP.reviveJSON); ! if (String(otp.totp()) !== String(request.payload)) { return reply({ valid: false }).code(403); } ! reply({ valid: true }); }); }