Secure Storage Plugin for NativePHP Mobile#
Secure key-value storage using iOS Keychain and Android EncryptedSharedPreferences.
Overview#
The SecureStorage API provides encrypted storage for sensitive data like tokens, credentials, and user secrets.
Installation#
composer require nativephp/mobile-secure-storage
Usage#
PHP (Livewire/Blade)#
use Native\Mobile\Facades\SecureStorage; // Store a valueSecureStorage::set('auth_token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'); // Retrieve a value$token = SecureStorage::get('auth_token'); if ($token) { // Use the token} // Delete a valueSecureStorage::delete('auth_token');
JavaScript (Vue/React/Inertia)#
import { SecureStorage } from '#nativephp'; // Store a valueawait SecureStorage.set('auth_token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'); // Retrieve a valueconst result = await SecureStorage.get('auth_token');if (result.value) { console.log('Token:', result.value);} // Delete a valueawait SecureStorage.delete('auth_token');
Methods#
set(string $key, ?string $value): array#
Store or delete a value.
| Parameter | Type | Description |
|---|---|---|
key |
string | The key to store under |
value |
string|null | Value to store (null to delete) |
Returns: { success: true }
get(string $key): array#
Retrieve a stored value.
| Parameter | Type | Description |
|---|---|---|
key |
string | The key to retrieve |
Returns: { value: string } (empty string if not found)
delete(string $key): array#
Delete a stored value.
| Parameter | Type | Description |
|---|---|---|
key |
string | The key to delete |
Returns: { success: true }
Security#
Android#
- Uses
EncryptedSharedPreferenceswith Android Keystore - AES-256-GCM encryption for values
- AES-256-SIV encryption for keys
- Data is hardware-backed on supported devices
iOS#
- Uses iOS Keychain Services
- Data is encrypted at rest
- Protected by
kSecAttrAccessibleWhenUnlockedThisDeviceOnly - Hardware-backed on devices with Secure Enclave
Testing#
The plugin extends the NativePHP testing suite with secure-storage-specific helpers, so your app tests can fake and assert keystore activity without knowing any bridge internals:
use Native\Mobile\Testing\Native; it('stores the token on login', function () { Native::fakeBridge()->withSecureStorage(); Native::test(LoginScreen::class) ->tap('Sign in') ->assertStored('auth_token', 'fresh-token');}); it('reads the stored token on launch', function () { Native::fakeBridge()->withSecureStorage(['auth_token' => 'existing-token']); Native::test(SplashScreen::class) ->tap('Check session') ->assertRetrieved('auth_token') ->assertSet('token', 'existing-token');}); it('clears the token on logout', function () { Native::fakeBridge()->withSecureStorage(['auth_token' => 'existing-token']); Native::test(AccountScreen::class) ->tap('Log out') ->assertDeleted('auth_token');});
Helpers#
withSecureStorage(array $initial = [])— fake the secure keystore's contents, seeded with$initialkey/value pairs. Set writes into the backing store and reports success; Get reads the current value for a key; Delete removes it — so a set → get → delete flow behaves like a real keychain.assertStored(?string $key = null, ?string $value = null)— assert something was stored, or exactly$key(optionally requiring the exact$valuestored under it) when given.assertRetrieved(?string $key = null)— assert something was retrieved, or exactly$keywhen given.assertDeleted(?string $key = null)— assert something was deleted, or exactly$keywhen given.assertNothingStored()— assert no write happened.
The helpers are available on Native::fakeBridge() and chain directly off Native::test(...). They register automatically while running tests (requires a core with a macroable FakeBridge; on older cores they simply don't register).
Examples#
Store User Credentials#
use Native\Mobile\Facades\SecureStorage; public function login($email, $password){ // Authenticate... $token = $this->authenticate($email, $password); // Store token securely SecureStorage::set('auth_token', $token); SecureStorage::set('user_email', $email);} public function logout(){ SecureStorage::delete('auth_token'); SecureStorage::delete('user_email');}
Check Stored Credentials on App Launch#
use Native\Mobile\Facades\SecureStorage; public function checkAuth(){ $token = SecureStorage::get('auth_token'); if ($token && !empty($token['value'])) { // Auto-login with stored token return $this->loginWithToken($token['value']); } return redirect('/login');}