PHPackages                             alvinfadli/access-lock - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. alvinfadli/access-lock

ArchivedLibrary[Authentication &amp; Authorization](/categories/authentication)

alvinfadli/access-lock
======================

A lightweight password-protected access gate middleware for Laravel applications.

v1.0.10(4w ago)0461[1 issues](https://github.com/alvinfadli/access-lock/issues)MITPHPPHP ^8.2

Since May 12Pushed 3w agoCompare

[ Source](https://github.com/alvinfadli/access-lock)[ Packagist](https://packagist.org/packages/alvinfadli/access-lock)[ RSS](/packages/alvinfadli-access-lock/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (9)Versions (12)Used By (0)

access-lock
===========

[](#access-lock)

A lightweight Laravel package that password-protects your application (or specific routes) using a middleware, a JavaScript `prompt()`, and Laravel session storage.

> **Not intended for production-grade authentication.** Use this as a simple access gate — e.g. for staging environments, internal tools, or early-access previews.

---

Requirements
------------

[](#requirements)

DependencyVersionPHP^8.2Laravel^10.0 or ^11.0---

Installation
------------

[](#installation)

### 1. Install via Composer

[](#1-install-via-composer)

```
composer require alvinfadli/access-lock
```

The service provider is auto-discovered; no manual registration is needed.

### 2. Set a Password

[](#2-set-a-password)

Run the Artisan command to set the access password:

```
php artisan access-lock:set-password
```

You will be prompted to enter and confirm a password. The bcrypt hash is automatically written to your `.env` file as:

```
ACCESS_LOCK_PASSWORD_HASH="$2y$12$..."

```

If you cache your configuration, clear it afterwards:

```
php artisan config:clear
```

---

Usage
-----

[](#usage)

### Web (Monolith / Blade)

[](#web-monolith--blade)

> **Important:** always add this middleware inside the **`web` group**, never in the global middleware stack. The global stack runs before `StartSession`, so `$request->session()` would not be available yet and you would get a *"Session store not set on request"* error.

**Laravel 10 — `app/Http/Kernel.php`**

Add it to the `web` group (after `StartSession`):

```
protected $middlewareGroups = [
    'web' => [
        // ... existing entries ...
        \AlvinFadli\AccessLock\Http\Middleware\AccessLockMiddleware::class,
    ],
];
```

**Laravel 11 / 12 / 13 — `bootstrap/app.php`**

Use `appendToGroup('web', ...)` — **not** `append()`:

```
->withMiddleware(function (Middleware $middleware) {
    $middleware->appendToGroup('web', \AlvinFadli\AccessLock\Http\Middleware\AccessLockMiddleware::class);
})
```

---

### API (Decoupled / SPA / Mobile)

[](#api-decoupled--spa--mobile)

For decoupled setups (e.g. Angular, React, Vue, or mobile apps talking to a Laravel API), use the `access.lock.api` middleware instead. It is token-based and returns JSON responses rather than redirecting to a Blade view.

#### 1. Protect your API routes

[](#1-protect-your-api-routes)

```
// routes/api.php
Route::middleware('access.lock.api')->group(function () {
    Route::apiResource('/users', UserController::class);
    // ... other protected routes
});
```

#### 2. Obtain a token

[](#2-obtain-a-token)

POST the staging password to the built-in unlock endpoint. No authentication is required for this endpoint — it is the entry point.

```
POST /api/access-lock/unlock
Content-Type: application/json

{ "password": "your-staging-password" }

```

**Success (200):**

```
{ "token": "your-staging-token", "expires_in": 120 }
```

**Wrong password (401):**

```
{ "message": "Invalid password." }
```

#### 3. Use the token on subsequent requests

[](#3-use-the-token-on-subsequent-requests)

Include the token on every protected API request using one of two headers:

```
Authorization: Bearer your-staging-password

```

or

```
X-Access-Lock-Token: your-staging-password

```

The middleware verifies the token against the configured bcrypt hash on every request — no session or cache storage is needed.

#### How it works

[](#how-it-works)

1. The client POSTs the password to `/api/access-lock/unlock`.
2. The package verifies it using `access_lock_verify()`.
3. On success, the plain-text password is returned as a token.
4. The client stores the token (e.g. `localStorage`) and sends it with every subsequent request.
5. `AccessLockApiMiddleware` calls `access_lock_verify(token)` on each request — if it matches the configured hash, the request passes through; otherwise it returns `403`.

---

### Protect a Route Group (web)

[](#protect-a-route-group-web)

```
Route::middleware('access.lock')->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
    Route::get('/reports', [ReportController::class, 'index']);
});
```

---

### Protect a Single Route (web)

[](#protect-a-single-route-web)

```
Route::get('/secret', [SecretController::class, 'index'])->middleware('access.lock');
```

---

### Protect a Route Group (api)

[](#protect-a-route-group-api)

```
Route::middleware('access.lock.api')->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
    Route::get('/reports', [ReportController::class, 'index']);
});
```

---

### Protect a Single Route (api)

[](#protect-a-single-route-api)

```
Route::get('/secret', [SecretController::class, 'index'])->middleware('access.lock.api');
```

---

How It Works (Web)
------------------

[](#how-it-works-web)

1. A visitor hits a protected route.
2. `AccessLockMiddleware` checks the Laravel session for `access_lock_unlocked = true`.
3. If not unlocked, the visitor is redirected to `/access-lock`.
4. The unlock page loads and a `window.prompt()` dialog appears automatically.
5. The visitor enters the password and it is submitted via `POST`.
6. If correct, the session flag is set and the visitor is redirected back to the original URL.
7. If incorrect, the unlock page reloads with an error message.

---

How It Works (API)
------------------

[](#how-it-works-api)

1. A client (SPA, mobile app, etc.) hits a protected API route.
2. `AccessLockApiMiddleware` checks for a valid token in the `Authorization: Bearer` or `X-Access-Lock-Token` header.
3. If no valid token is found, the request is rejected with a `401` or `403` response.
4. The client obtains a token by POSTing the password to the `/api/access-lock/unlock` endpoint.
5. On success, the server returns the plain-text password as a token (for convenience in decoupled setups).
6. The client stores the token and includes it on every subsequent request.
7. `AccessLockApiMiddleware` calls `access_lock_verify(token)` on each request — if it matches the configured hash, the request passes through; otherwise it returns `403`.

---

Publishing Assets
-----------------

[](#publishing-assets)

### Publish Config

[](#publish-config)

```
php artisan vendor:publish --tag=access-lock-config
```

This copies `config/access-lock.php` to your application's `config/` directory so you can customise it.

### Publish Views

[](#publish-views)

```
php artisan vendor:publish --tag=access-lock-views
```

This copies the unlock Blade view to `resources/views/vendor/access-lock/` for customisation.

### Publish Everything

[](#publish-everything)

```
php artisan vendor:publish --tag=access-lock
```

---

Configuration
-------------

[](#configuration)

After publishing, edit `config/access-lock.php`:

```
return [
    // Bcrypt hash of the access password (set via Artisan command).
    'password_hash' => env('ACCESS_LOCK_PASSWORD_HASH', null),

    // Session key used to track unlocked state.
    'session_key' => 'access_lock_unlocked',

    // URL prefix for the unlock page routes (/access-lock by default).
    'route_prefix' => 'access-lock',

    // Bypass conditions — see "Bypass Conditions" section below.
    'bypass' => [
        'query'   => [],
        'headers' => [],
    ],

    // Setup API token TTL (in seconds)
    'api' => [
        'token_ttl' => env('ACCESS_LOCK_API_TOKEN_TTL', 120),
    ],
];
```

---

Bypass Conditions
-----------------

[](#bypass-conditions)

You can configure query string parameters or request headers that **automatically and permanently unlock the session** for a visitor — no password prompt is shown.

This is useful for automated tools, CI checks, SSO redirects, or any trusted caller that should never see the lock screen.

### Setup

[](#setup)

Publish the config and list the query keys / header names you want to act as bypass signals:

```
php artisan vendor:publish --tag=access-lock-config
```

```
// config/access-lock.php
'bypass' => [

    // All listed query keys must be present and non-empty to bypass.
    // e.g. visiting /?ssoKey=anything&userId=123 will unlock the session.
    'query' => [
        'ssoKey',
        'userId',
    ],

    // All listed header names must be present and non-empty to bypass.
    // e.g. sending X-SSO-Key: anything will unlock the session.
    'headers' => [
        'X-SSO-Key',
    ],

],
```

---

Helper Functions
----------------

[](#helper-functions)

The package provides three global helpers:

```
// Returns true if a password hash has been configured.
access_lock_active(): bool

// Returns true if the current visitor has already unlocked access.
access_lock_unlocked(): bool

// Verifies a plain-text password against the configured hash.
access_lock_verify(string $password): bool
```

---

Setting Password Programmatically
---------------------------------

[](#setting-password-programmatically)

```
use AlvinFadli\AccessLock\Support\PasswordManager;

PasswordManager::setPassword('my-plain-text-password');
```

---

Middleware Reference
--------------------

[](#middleware-reference)

AliasClassUse case`access.lock``AccessLockMiddleware`Monolith / Blade apps — session-based, redirects to prompt page`access.lock.api``AccessLockApiMiddleware`Decoupled / API apps — token-based, returns JSON---

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

44

—

FairBetter than 90% of packages

Maintenance94

Actively maintained with recent releases

Popularity12

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 81.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

11

Last Release

28d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/dd31e185f5f6bc1bac2b3091c30f8e01d98f4e7f870bae310c2e303933b8ffe4?d=identicon)[alvinfadli](/maintainers/alvinfadli)

---

Top Contributors

[![alvinfadli](https://avatars.githubusercontent.com/u/90144441?v=4)](https://github.com/alvinfadli "alvinfadli (9 commits)")[![akbarrahmatm](https://avatars.githubusercontent.com/u/88664674?v=4)](https://github.com/akbarrahmatm "akbarrahmatm (2 commits)")

---

Tags

middlewarelaravelpasswordaccessgate

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/alvinfadli-access-lock/health.svg)

```
[![Health](https://phpackages.com/badges/alvinfadli-access-lock/health.svg)](https://phpackages.com/packages/alvinfadli-access-lock)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3325.1M337](/packages/psalm-plugin-laravel)[laravel/mcp

Rapidly build MCP servers for your Laravel applications.

76318.2M110](/packages/laravel-mcp)[larastan/larastan

Larastan - Discover bugs in your code without running it. A phpstan/phpstan extension for Laravel

6.4k51.0M7.4k](/packages/larastan-larastan)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9732.3M121](/packages/roots-acorn)[laravel/ai

The official AI SDK for Laravel.

9782.1M153](/packages/laravel-ai)[laravel/surveyor

Static analysis tool for Laravel applications.

8390.3k12](/packages/laravel-surveyor)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
