- How do I install fouladgar/laravel-otp in a Laravel application?
- Install with composer require fouladgar/laravel-otp, then publish the config file and the migration using the vendor:publish command before running the migration yourself. Next, add the recipient contract or trait to the model that should receive codes and implement a sender for your chosen channel. Realistically this is a one to three day spike for a mid-level Laravel engineer, including a production-grade sender implementation.
- Which Laravel and PHP versions does this OTP package support?
- The package declares illuminate/* and PHP constraints in its composer.json, but with low adoption those constraints likely predate current framework releases. Check the declared constraints and run composer why-not fouladgar/laravel-otp to confirm it installs cleanly on your target version, then verify the test suite passes there. Never accept a framework downgrade just to use an OTP package.
- How do I actually send the OTP code via SMS or email?
- The package is channel-agnostic and provides a driver/config abstraction rather than hard-coupling you to one SMS vendor. You implement the sender and wire it to your provider such as Twilio, SNS, or Laravel notifications, which means retries, failover, and idempotency are your responsibility. Make the sender async-friendly so delivery can be queued instead of blocking the request.
- Can I use it for phone verification, password reset, and two-factor login?
- Yes. Recipients are polymorphic through a morph relation, so a User model, a raw phone number, an email address, or any other model can receive a code. That lets one token table serve login, registration, password reset, phone verification, and step-up 2FA without a schema change per feature. Make sure the migration is published rather than auto-run so you control the rollout.
- Is the OTP stored hashed at rest, and is validation constant-time?
- That is the first thing to audit: confirm whether codes are stored hashed or encrypted rather than plaintext, and whether validation uses hash_equals for constant-time comparison. Also verify single-use enforcement, TTL checked against the server clock, and that prior codes are invalidated on re-issue. If any of these are missing, treat them as remediation items or fork the package under its MIT license.
- How do I configure OTP length, expiry, and resend limits?
- Publish the config file with vendor:publish and set the OTP digit length, expiry window, and resend cooldown there. Keep these values environment-driven so you can tune them without a code deploy. Longer expiry and shorter codes trade usability against brute-force resistance, so align the settings with your threat model.
- Does it include rate limiting and brute-force protection?
- The package provides resend and rate limits, but per-recipient lockout and max-attempt counters should be verified in the code before you trust them. Many small OTP packages omit attempt throttling entirely, in which case you add it in middleware or a wrapper service. Throttle on both the recipient and the requesting IP to blunt enumeration and spraying.
- How do I test OTP flows in my Laravel test suite?
- Because generation and validation sit behind a facade and service provider, you can swap the sender for a fake or use Notification::fake() and assert the code was generated and delivered. Cover the validation, expiry, and replay paths specifically since those are the security-critical ones. Use Carbon::setTestNow to freeze the clock for TTL tests.
- Is fouladgar/laravel-otp actively maintained, and what are the alternatives?
- Adoption is low at roughly 221 stars and zero dependents, and the project is single-maintainer, so third-party scrutiny and release cadence are limited. Check the last 12 months of commits, issues, and any security disclosure policy before relying on it in production. Alternatives include a small in-house token service, Fortify or Passport two-factor features, or an identity provider that owns OTP, and MIT licensing means forking is a viable mitigation.
- Can I use this OTP package in a multi-tenant app or with a custom recipient model?
- Custom recipient models work well through the polymorphic morph relation, but confirm the morph columns are indexed for query performance. Multi-tenancy needs extra work because the shared token table requires a tenant key and scoped queries, so plan for that if you have hard data-isolation requirements. Wrap the package behind your own OtpService interface so business code never imports the vendor namespace directly.