Using a Single Input for one-time-code (2024)

Mads Stoumann

Posted on

Using a Single Input for one-time-code (3) Using a Single Input for one-time-code (4) Using a Single Input for one-time-code (5) Using a Single Input for one-time-code (6) Using a Single Input for one-time-code (7)

#css #javascript #webdev #showdev

The other night I had a bit of fun trying to create a single-input one-time-code:

Using a Single Input for one-time-code (8)

one-time-code is a valid autocomplete-value, and with a few lines of JS, it let's you fill out the field from a text-message (sms).

More often, it's called OTP, though.

From Wikipedia:

A one-time password (OTP), also known as a one-time PIN, one-time authorization code (OTAC) or dynamic password, is a password that is valid for only one login session or transaction, on a computer system or other digital device.

Back to my example.

It's using very simple markup:

<input type="text" autocomplete="one-time-code" inputmode="numeric" maxlength="6" pattern="\d{6}">

The CSS is a bit more complex:

:where([autocomplete=one-time-code]) { --otp-digits: 6; /* length */ --otc-ls: 2ch; --otc-gap: 1.25; /* private consts */ --_otp-bgsz: calc(var(--otc-ls) + 1ch); all: unset; background: linear-gradient(90deg, var(--otc-bg, #EEE) calc(var(--otc-gap) * var(--otc-ls)), transparent 0 ) 0 0 / var(--_otp-bgsz) 100%; caret-color: var(--otc-cc, #333); clip-path: inset(0% calc(var(--otc-ls) / 2) 0% 0%); font-family: ui-monospace, monospace; font-size: var(--otc-fz, 2.5em); inline-size: calc(var(--otc-digits) * var(--_otp-bgsz)); letter-spacing: var(--otc-ls); padding-block: var(--otc-pb, 1ch); padding-inline-start: calc(((var(--otc-ls) - 1ch) / 2) * var(--otc-gap));}

It's a bunch of stuff simulating 6 fields (from the property --otc-digits), while — in reality — it's just a single <input>. The spacing between the "fields" is due to letter-spacing, and the gray "boxes" are from a linear-gradient.

It has to use a monospace-font, so the magic value of 1ch works — same applies to the letter-spacing. 1ch equals the width of a zero.

But why?

Have you ever created a OTP-component before?

I'm writing "component", because it's typically a <fieldset> with six <input>s and a bunch of JavaScript to detect when you enter- or leave a field etc.

When you fill out the field from the Web OTP API, you need to split the value, and fill-in six fields instead of one.

With a single input it's much simpler:

navigator.credentials.get({ otp: {transport:['sms']}}).then(otp => input.value = otp.code);

Highlightning the current "field"

The single-input OTP is not perfect. When you move from "field" to "field", it would be a better user-experience, if the caret was a block:

.selector { caret-shape: block;}

Unfortunately, no browsers support caret-shape yet.

Another way, would be to add another background-gradient, but without repeating the pattern:

Using a Single Input for one-time-code (9)

And position it by multiplying the size-property — --_otp-bgsz — with the digit-number, --_otp-digit, as a custom property:

.selector { background-position: calc(var(--_otp-digit, 0) * var(--_otp-bgsz)) 0;}

This is not perfect, because we'd need to put the digit in a CSS Custom Property, and then update that with JavaScript:

input.addEventListener('input', () => input.style.setProperty('--_otp-digit', input.selectionStart))

Could this be done in an even simpler way? Other sugestions? Please use the comments!

Here's a Codepen-demo:

Top comments (24)

Subscribe

Rasmus Schultz

Rasmus Schultz

Passionate web-developer since 1998 using various languages, databases and tools. Opinions all my own.

  • Joined

Jun 14 '23

  • Copy link

First, I love that you went through the trouble of doing this properly! 👍

I've seen a bunch of sites where you can't, for example, copy and paste the code, because they're individual inputs, which is just super annoying.

And you don't even mention accessibility, but I'm sure this is much better than 6 inputs for people using a screen reader as well.

You could probably adapt this approach to work for credit card number inputs as well? Those are also often some awful combination of multiple inputs, or key event handlers replacing underscores and moving the cursor around, yeesh. 😅

Now, I have to ask though - for these one time codes, why do people use inputs at all? 🤔

I mean, couldn't you just send me a link with the same code in a query string, so I could continue instantly, by just tapping the link? That would be so much simpler and more convenient.

Is that any less secure, or why do people do it this way in the first place? Do you know?

Matt Ellen-Tsivintzeli

Matt Ellen-Tsivintzeli

Ultra-fullstack software developer. Python, JavaScript, C#, C.

  • Location

    Earth

  • Education

    I am a master of science

  • Pronouns

    He/him/his/his

  • Work

    Software Engineer

  • Joined

Jun 14 '23 • Edited on Jun 14 • Edited

  • Copy link

OTP is meant to be the "something you have" factor1 (as opposed to your password, which is the "something you know" factor). So that's why the generators are on your phone (and not linked to any kind of account) or sent via SMS to your phone (which is less secure due to the possibility of SIM cloning), or done with some external bit of hardware.

Your email account is not a physical thing, so it is not a "something you have" factor, it is a "something you know", as it can also be accessed via a password.

  1. en.wikipedia.org/wiki/Multi-factor...

Rasmus Schultz

Rasmus Schultz

Passionate web-developer since 1998 using various languages, databases and tools. Opinions all my own.

  • Joined

Jun 14 '23

  • Copy link

I'm not sure if this really answers my question. 😅

According to the wikipedia entry you quoted in your article:

An email is one of the common ways of using OTACs. There are two main methods used. With the first method, a service provider sends a personalised one time URL to an authenticated email address e.g. @ucl.ac.uk; when the user clicks the URL, the server authenticates the user.[25] With the second method, a service provider sends a personalised OTAC (e.g. an enciphered token) to an authenticated email address; when the user types the OTAC into the website, the server authenticates the user.

More often than not, I'll get these codes via email.

Your email account is not a physical thing, so it is not a "something you have" factor, it is a "something you know", as it can also be accessed via a password.

I don't think you are correct about that.

From my understanding, "something you know" refers to information that only the user should know, such as a password, a PIN, or a security question answer.

Whereas "something you have" would involve possessing a physical or digital object that only the user should have access to, such as a smartphone, a hardware token, or an email account.

If you're a bank, you obviously shouldn't use email for this (because of possible email interception, account recovery risks, etc.) but plenty of online shops and services use them - and in a 2FA scheme, I'm fairly certain your email account is considered "something you have".

If your implementation doesn't use or allow email, you're probably not the right person to answer my original question though. The Wikipedia article only says those two forms of authentication exist - what I'd really like to know is why anyone would use a code you have to copy, rather than a link you can just click. It's much less convenient, and from my understanding seems to equally prove that you had access to that email account, so what would be the point of using anything other than a link. 🤔

Matt Ellen-Tsivintzeli

Matt Ellen-Tsivintzeli

Ultra-fullstack software developer. Python, JavaScript, C#, C.

Jun 14 '23 • Edited on Jun 14 • Edited

  • Copy link

Yes, a one time password can be received by email, such as a password reset request, but that's not the same as the OTP generated by e.g. Authy.

To quote the article you quote from:

a number of implementations [of OTPs] also incorporate two-factor authentication by ensuring that the one-time password requires access to something a person has (such as a small keyring fob device with the OTP calculator built into it, or a smartcard or specific cellphone)

An email account is not something physical a person has, as detailed in the MFA article I linked to:

Something the user has: Any physical object in the possession of the user, such as a security token (USB stick), a bank card, a key, etc.

It can be argued that if your email is secured by 2FA then it could proxy 2FA, but I think that would not be enough in most instances, as there are ways around having to use 2FA to log in.

An email account is "something you know" in essence, not literally, as it is possible to access it with only something you know, e.g. if it's only secured with a password, so essentially proxies that factor.

There are apps, e.g. the github app, that act as a second factor that don't require a user to input a OTP, which I think fits your request.

When I make an online payment, I log into my banking app, approve the payment there and then click the button in the website, no user input OTP required.

A link in an email does not count as a second factor.

Matt Ellen-Tsivintzeli

Matt Ellen-Tsivintzeli

Ultra-fullstack software developer. Python, JavaScript, C#, C.

  • Location

    Earth

  • Education

    I am a master of science

  • Pronouns

    He/him/his/his

  • Work

    Software Engineer

  • Joined

Jun 14 '23

  • Copy link

Just to clarify, the OTP generated by e.g. Authy is (supposedly) proof that you have a physical object, i.e. your phone. That's what makes it a second factor.

A link in an email can never prove you have a particular physical object, so it cannot be a second factor.

Rasmus Schultz

Rasmus Schultz

Passionate web-developer since 1998 using various languages, databases and tools. Opinions all my own.

  • Joined

Jun 14 '23

  • Copy link

I think this can vary - it seems to depend on what is acceptable as a "factor" in a given (legal) context.

For example, email appears to be good enough for e-commerce here in the EU:

eur-lex.europa.eu/legal-content/EN...

The security measures should be compatible with the level of risk involved in the payment service. In order to allow the development of user-friendly and accessible means of payment for low-risk payments, such as low value contactless payments at the point of sale, whether or not they are based on mobile phone, the exemptions to the application of security requirements should be specified in regulatory technical standards. Safe use of personalised security credentials is needed to limit the risks relating to phishing and other fraudulent activities. In that respect, the user should be able to rely on the adoption of measures that protect the confidentiality and integrity of personalised security credentials. Those measures typically include encryption systems based on personal devices of the payer, including card readers or mobile phones, or provided to the payer by its account servicing payment service provider via a different channel, such as by SMS or email. The measures, typically including encryption systems, which may result in authentication codes such as one-time passwords, are able to enhance the security of payment transactions. The use of such authentication codes by payment service users should be considered to be compatible with their obligations in relation to payment instruments and personalised security credentials also when payment initiation service providers or account information service providers are involved.

From my understanding, two-factor authentication (2FA) has no formal definition or standard - so what goes as a factor is going to depend on the specific context.

As said, many shops and services do use email for this - they do refer to this as "two-factor" or "multi-factor" authentication, and in that context, your email account itself (and not the code you use to log into that email account) is considered as "something you have".

I think the definitions are going to vary depending on who you're talking to, what they're authenticating access to, what rules and regulations apply, and so on?

Mads Stoumann

Mads Stoumann

I'm a web developer, graphic designer, type designer, musician, comicbook-geek, LEGO-collector, food lover … as well as husband and father, located just south of Copenhagen, Denmark.

  • Location

    Copenhagen

  • Work

    Co-Founder at Perfection.DEV

  • Joined

Jun 14 '23 • Edited on Jun 14 • Edited

  • Copy link

It's a broad topic, for sure, and — as you mention — some of the 2FA-options are not needed. For instance, HumbleBundle and Steam send you an email with a passcode, you need to enter.

That could just as well be a link.

GitHub use email/password and then a 2FA-method of choice.
I'm using a YubiKey, with a text-message as fallback.
On a MacBook with touch-login, you can set that up as a 2FA-method as well (also with Github)

For me, the OTP makes sense when you're logging in from a device capable of receiving a text-message, so you can just auto-fill the code through the API. Otherwise, it can be annoying.

And speaking of annoying, let me tell you about a system we have in Denmark called "MyID" ;-)

  1. When you log into any government webpage, you need to fill out your MyId-username, and click on sign-in.
  2. Then you open your MyID-app, and log in with either a biometric method (face or finger) or passcode.
  3. Next, you need to scan a QR-code on the webpage you're visiting
  4. Finally, you can swipe the "Sign in"-button in the app, and ...
  5. The webpage redirects you to the signed-in area

Rasmus Schultz

Rasmus Schultz

Passionate web-developer since 1998 using various languages, databases and tools. Opinions all my own.

  • Joined

Jun 14 '23

  • Copy link

I'm actually Danish too. 😄

I think the process you're describing is when you first connect your bank (or other service) to your ID? When I confirm a purchase or log into online banking, I just log in (username and password) and open the app on my phone, then swipe to confirm. 🙂

Mads Stoumann

Mads Stoumann

I'm a web developer, graphic designer, type designer, musician, comicbook-geek, LEGO-collector, food lover … as well as husband and father, located just south of Copenhagen, Denmark.

  • Location

    Copenhagen

  • Work

    Co-Founder at Perfection.DEV

  • Joined

Jun 14 '23

  • Copy link

Hej! I think it's a new thing, when you're not logging in from the device with the app, ie. your computer. At least I had to scan the QR-code and all that for the various sites related to having a company — and it was very annoying!

Mads Stoumann

Mads Stoumann

I'm a web developer, graphic designer, type designer, musician, comicbook-geek, LEGO-collector, food lover … as well as husband and father, located just south of Copenhagen, Denmark.

  • Location

    Copenhagen

  • Work

    Co-Founder at Perfection.DEV

  • Joined

Jun 14 '23 • Edited on Jun 14 • Edited

This is what I’m talking about: mitid.dk/hjaelp/hjaelpeunivers/mit...

Mads Stoumann

Mads Stoumann

I'm a web developer, graphic designer, type designer, musician, comicbook-geek, LEGO-collector, food lover … as well as husband and father, located just south of Copenhagen, Denmark.

  • Location

    Copenhagen

  • Work

    Co-Founder at Perfection.DEV

  • Joined

Jun 14 '23

  • Copy link

Exactly! Thanks for clarifying 2FA!

Jamie Warburton

Jamie Warburton

  • Joined

Aug 13 '23 • Edited on Aug 13 • Edited

  • Copy link

You're describing multi-factor authentication (or 2FA as it's often called). That's where your link points too. For OTP, you want this article: en.wikipedia.org/wiki/One-time_pas...

OTP is often used for multi-factor auth, but neither are exclusive to each other. For example OTP can be used in place of a password for single-factor authentication, and a physical keyfob could be used for multi-factor.

For the original question, the reason I offer OTP instead of just a link is two-part.

Firstly, it means I can get the code on one device, and enter it on another. E.G. access my emails on my mobile to get the OTP, and enter it on my laptop.

And secondly, for when you already have a window open which knows where I want to go next after login. If I click on a link, it's going to instead take me to a generic post-login page, but if I enter the code in my existing flow I can continue in that flow.

This is also useful for OAuth 2.0, so that I can continue whatever action on site A I was doing after authenticating on site B via the OTP. Otherwise I'd need to go back, refresh, and do my action again.

My preferred implementation would have both a code and a link, so the user can decide.

Dan Bolser

Dan Bolser

Hi

  • Email

  • Location

    Space

  • Education

    Cambridge, uk

  • Pronouns

    Conventional/Un

  • Work

    CEO Geromics

  • Joined

Jun 18 '23

  • Copy link

1) lazy devs copy patterns without thinking.
2) the code let's you easily cross platform, e.g. laptop/mobile

Mads Stoumann

Mads Stoumann

I'm a web developer, graphic designer, type designer, musician, comicbook-geek, LEGO-collector, food lover … as well as husband and father, located just south of Copenhagen, Denmark.

  • Location

    Copenhagen

  • Work

    Co-Founder at Perfection.DEV

  • Joined

Jun 14 '23

  • Copy link

Thank you! Good idea for the credit cards-entry. I'd look into that + Temanis box-gradient-example ;-)

Temani Afif

Temani Afif

Your favorite CSS Hacker

  • Joined

Jun 12 '23

  • Copy link

Reminds a similar idea I did to style numbers and put them inside boxes: css-tip.com/number-inside-box/ (I also made a border-only version)

Mads Stoumann

Mads Stoumann

I'm a web developer, graphic designer, type designer, musician, comicbook-geek, LEGO-collector, food lover … as well as husband and father, located just south of Copenhagen, Denmark.

  • Location

    Copenhagen

  • Work

    Co-Founder at Perfection.DEV

  • Joined

Jun 12 '23

  • Copy link

Nice! Will try the "box" for the "current position"

Hayley Grace

Hayley Grace

Software developer from little ol' NZ

  • Education

    Victoria University of Wellington

  • Work

    Front end developer for a digital agency

  • Joined

Nov 1 '23

  • Copy link

This is really cool, and has been pretty helpful for me so far. I am having trouble though, where the cursor sits at exactly the left edge of the grey square so the numbers end up positioned to the left of the 'input' instead of in the middle. Which property is it that controls this position? Is it the padding-inline-start? I've played around with the code fiddle but while it works in there it doesn't work in my React project as nicely. Any help appreciated!

Mads Stoumann

Mads Stoumann

I'm a web developer, graphic designer, type designer, musician, comicbook-geek, LEGO-collector, food lover … as well as husband and father, located just south of Copenhagen, Denmark.

  • Location

    Copenhagen

  • Work

    Co-Founder at Perfection.DEV

  • Joined

Nov 1 '23

  • Copy link

Hi,
Try fiddling with padding-inline-start. Change the 2 in the division to 1.5 or smaller, to move the text right.
/Mads

Koas

Koas

Programming is easy like riding a bike. Except the bike is on fire and you're on fire and everything is on fire and you're actually in hell (@matixmatix)

  • Location

    Madrid, Spain

  • Joined

Jun 15 '23

  • Copy link

Amazing article! And the final result works great, congratulations!
Also, kudos for using logical properties! 👌🏻

Mads Stoumann

Mads Stoumann

I'm a web developer, graphic designer, type designer, musician, comicbook-geek, LEGO-collector, food lover … as well as husband and father, located just south of Copenhagen, Denmark.

  • Location

    Copenhagen

  • Work

    Co-Founder at Perfection.DEV

  • Joined

Jun 17 '23

  • Copy link

Thank you!

YJDoc2

YJDoc2

  • Joined

Jun 15 '23

  • Copy link

Hey really nice article! The actual implementation is pretty cool, and I really liked reading the blog itself too :) Nicely short and sweet! Thanks for writing and sharing 😄

Mads Stoumann

Mads Stoumann

I'm a web developer, graphic designer, type designer, musician, comicbook-geek, LEGO-collector, food lover … as well as husband and father, located just south of Copenhagen, Denmark.

  • Location

    Copenhagen

  • Work

    Co-Founder at Perfection.DEV

  • Joined

Jun 15 '23

  • Copy link

Thank you!

Lars Rye Jeppesen

Lars Rye Jeppesen

  • Joined

Jun 12 '23

  • Copy link

Thanks

Ritik Banger

Ritik Banger

I am a Full Stack Javascript Engineer with robust problem-solving skills and proven experience in creating and designing web apps in a test driven environment and deploy them to cloud servers.

  • Location

    Jaipur, India

  • Education

    B.Tech, Computer Engineering

  • Joined

Jun 14 '23

  • Copy link

I have created a npm package- react18-input-otp, you can also use that.

View full discussion (24 comments)

For further actions, you may consider blocking this person and/or reporting abuse

Using a Single Input for one-time-code (2024)
Top Articles
7 Tips for Coaching Employees to Improve Performance
What is BIOS? A Guide for Beginners | Simplilearn
English Bulldog Puppies For Sale Under 1000 In Florida
Katie Pavlich Bikini Photos
Gamevault Agent
Pieology Nutrition Calculator Mobile
Hocus Pocus Showtimes Near Harkins Theatres Yuma Palms 14
Hendersonville (Tennessee) – Travel guide at Wikivoyage
Compare the Samsung Galaxy S24 - 256GB - Cobalt Violet vs Apple iPhone 16 Pro - 128GB - Desert Titanium | AT&T
Vardis Olive Garden (Georgioupolis, Kreta) ✈️ inkl. Flug buchen
Craigslist Dog Kennels For Sale
Things To Do In Atlanta Tomorrow Night
Non Sequitur
Crossword Nexus Solver
How To Cut Eelgrass Grounded
Pac Man Deviantart
Alexander Funeral Home Gallatin Obituaries
Energy Healing Conference Utah
Geometry Review Quiz 5 Answer Key
Hobby Stores Near Me Now
Icivics The Electoral Process Answer Key
Allybearloves
Bible Gateway passage: Revelation 3 - New Living Translation
Yisd Home Access Center
Home
Shadbase Get Out Of Jail
Gina Wilson Angle Addition Postulate
Celina Powell Lil Meech Video: A Controversial Encounter Shakes Social Media - Video Reddit Trend
Walmart Pharmacy Near Me Open
Marquette Gas Prices
A Christmas Horse - Alison Senxation
Ou Football Brainiacs
Access a Shared Resource | Computing for Arts + Sciences
Vera Bradley Factory Outlet Sunbury Products
Pixel Combat Unblocked
Movies - EPIC Theatres
Cvs Sport Physicals
Mercedes W204 Belt Diagram
Mia Malkova Bio, Net Worth, Age & More - Magzica
'Conan Exiles' 3.0 Guide: How To Unlock Spells And Sorcery
Teenbeautyfitness
Where Can I Cash A Huntington National Bank Check
Topos De Bolos Engraçados
Sand Castle Parents Guide
Gregory (Five Nights at Freddy's)
Grand Valley State University Library Hours
Holzer Athena Portal
Hello – Cornerstone Chapel
Stoughton Commuter Rail Schedule
Nfsd Web Portal
Selly Medaline
Latest Posts
Article information

Author: Edmund Hettinger DC

Last Updated:

Views: 6222

Rating: 4.8 / 5 (78 voted)

Reviews: 85% of readers found this page helpful

Author information

Name: Edmund Hettinger DC

Birthday: 1994-08-17

Address: 2033 Gerhold Pine, Port Jocelyn, VA 12101-5654

Phone: +8524399971620

Job: Central Manufacturing Supervisor

Hobby: Jogging, Metalworking, Tai chi, Shopping, Puzzles, Rock climbing, Crocheting

Introduction: My name is Edmund Hettinger DC, I am a adventurous, colorful, gifted, determined, precious, open, colorful person who loves writing and wants to share my knowledge and understanding with you.