signInWithOTP
- One-Time Password Authentication
- Type:
(otpId: string, password: string, options?: AuthOptions) => AuthData
- Description: Authenticates a user with a one-time password, automatically setting the authentication cookie upon success.
Parameters
otpId
: The OTP record IDpassword
: The one-time password codeoptions
: (Optional) Authentication optionstype AuthOptions = { collection: string // The collection to authenticate against (defaults to "users") }
Basic Usage
<%
try {
// First request an OTP code
const { otpId } = requestOTP('[email protected]')
// Later, verify the OTP code
const authData = signInWithOTP(otpId, '123456')
// User is now logged in
redirect('/dashboard')
} catch (error) {
// Handle authentication error
}
%>
Return Value
Returns an AuthData
object containing:
interface AuthData {
token: string // The authentication token
record: {
// The authenticated user record
id: string
email: string
username: string
verified: boolean
// ... other user fields
}
}
Complete OTP Flow Example
<%
let error = null
let otpId = request.body().otpId || null
const {
mode,
otpCode,
identity
} = {
mode: 'otp-request',
...request.body()
}
if (request.method === 'POST') {
switch (mode) {
case 'otp-request':
try {
// Request a new OTP code
const res = requestOTP(identity)
otpId = res.otpId
} catch (e) {
error = e.message
}
break
case 'otp-confirm':
try {
// Verify the OTP code
const res = signInWithOTP(otpId, otpCode)
redirect('/', {
message: 'Login successful'
})
} catch (e) {
error = e.message
}
break
}
}
%>
<% if (error) { %>
<mark><%= error %></mark>
<% } %>
<h1>We have sent you an OTP code</h1>
<p>Please check your email for the OTP code and enter it below.</p>
<!-- OTP Verification Form -->
<form method="post">
<input type="hidden" name="mode" value="otp-confirm" />
<input type="hidden" name="otpId" value="<%= otpId %>" />
<input type="hidden" name="identity" value="<%= identity %>" />
<input type="text"
name="otpCode"
placeholder="OTP code"
inputmode="numeric"
pattern="[0-9]*"
autocomplete="one-time-code" />
<button type="submit">Login</button>
</form>
<!-- Request New OTP Form -->
<form method="post">
<input type="hidden" name="mode" value="otp-request" />
<input type="text"
name="identity"
placeholder="Email"
value="<%= identity %>" />
Didn't receive an OTP code?
<button type="submit">Resend OTP code</button>
</form>
Important Notes
Flow: A typical OTP authentication flow has two steps:
- Request OTP: Call
requestOTP(email)
to send the code - Verify OTP: Use
signInWithOTP(otpId, code)
to authenticate
- Request OTP: Call
Cookie Management: This function automatically:
- Authenticates with PocketBase
- Sets the authentication cookie
- Makes the user record available via
request.auth
Error Handling: Common errors to handle:
- Invalid or expired OTP
- Already used OTP
- Rate limiting errors
- Network/database errors
Security Considerations:
- OTPs should have a short expiration time
- Implement rate limiting for failed attempts
- Consider adding CSRF protection
- Clear OTP after successful use
- Use secure input patterns for OTP entry