Skip to main content

Email & OTP

Email magic links, email OTP, and phone/SMS OTP require an adapter for verification tokens.

Before each new code, goauth purges prior tokens for the same identifier (resend-safe). See Adapters — verification tokens.

import "github.com/izetmolla/goauth/providers/email"

email.New(email.Options{
SendVerificationRequest: func(ctx context.Context, p goauth.SendVerificationRequestParams) error {
return mailer.Send(p.Identifier, "Sign in", p.URL)
},
})
  1. POST /auth/signin/email with email=…
  2. User clicks link → GET /auth/callback/email?token=…&email=…

One-time code — email (OTP provider)

import "github.com/izetmolla/goauth/providers/otp"

otp.New(otp.Options{
CodeLength: 6,
MaxAge: 600,
SendCode: func(ctx context.Context, p goauth.SendVerificationRequestParams) error {
return mailer.Send(p.Identifier, "Code: "+p.Token)
},
// Optional: custom code with user context
GenerateCode: func(ctx context.Context, p goauth.GenerateVerificationTokenParams) string {
return goauth.NumericCode(6) // or any string token
},
})
  1. POST /auth/signin/otp with email=…
  2. POST /auth/callback/otp with email=…&code=123456 (also accepts otp or token)

GenerateVerificationTokenParams includes Identifier, Channel, Fields (full form), and User (when already registered).

One-time code — phone (phone provider)

import "github.com/izetmolla/goauth/providers/phone"

phone.New(phone.Options{
CodeLength: 6,
SendCode: func(ctx context.Context, p goauth.SendVerificationRequestParams) error {
return sms.Send(p.Identifier, "Code: "+p.Token) // p.Channel == "phone"
},
})
  1. POST /auth/signin/phone with phone=+15551234567
  2. POST /auth/callback/phone with phone=…&code=123456

Resend

Requesting a new code (same email/phone or MFA login again) invalidates the previous code. goauth calls DeleteVerificationTokensByIdentifier on the adapter before storing the new token.

Token flow

Add X-Auth-Flow: token on the callback POST to receive JSON tokens instead of a redirect.

Mask helpers (for UI hints)

goauth.MaskEmail("user@example.com") // u***@example.com
goauth.MaskPhone("+15551234567") // *******4567

Used with MFA delivery hints and optional SendVerificationRequestParams.Channel.