🏰 The Castle of Secrets: Protecting Your App’s Treasures
Imagine your app is a magical castle. Inside, you keep precious treasures—passwords, user secrets, and important data. But bad guys want to steal them! Let’s learn how to build the STRONGEST castle ever.
🗝️ The Story Begins…
Once upon a time, in the land of React Native, developers needed to keep their users’ secrets safe. They discovered five powerful shields:
- Biometric Authentication - The Magic Fingerprint Gate
- Secure Storage - The Invisible Vault
- Security Best Practices - The Knight’s Code
- SQLite Basics - The Royal Library
- SQLite Operations - The Librarian’s Skills
Let’s explore each one!
👆 Biometric Authentication: The Magic Fingerprint Gate
What Is It?
Think of your fingerprint or face like a magical key that only YOU have. No two people have the same fingerprint—just like snowflakes!
Real Life Example:
- You touch your phone → It recognizes YOUR finger → Door opens!
- Bad guy touches your phone → Wrong finger → Door stays LOCKED!
How It Works
graph TD A["User Wants In"] --> B{Scan Finger/Face} B -->|Match!| C["✅ Welcome!"] B -->|No Match| D["❌ Access Denied"]
Setting Up The Magic Gate
First, install the magic library:
npm install react-native-biometrics
Then, use it like this:
import ReactNativeBiometrics
from 'react-native-biometrics';
const rnBiometrics =
new ReactNativeBiometrics();
// Check if magic gate exists
async function checkBiometrics() {
const { available, biometryType } =
await rnBiometrics.isSensorAvailable();
if (available) {
console.log('Magic gate ready!');
console.log('Type:', biometryType);
}
}
Asking User to Prove Identity
async function authenticate() {
const result = await rnBiometrics
.simplePrompt({
promptMessage: 'Touch the magic gate!'
});
if (result.success) {
console.log('Welcome, friend!');
// Open the castle doors
} else {
console.log('Who goes there?!');
}
}
🎯 Key Points
- Face ID = Looking at a magic mirror
- Touch ID = Touching a magic stone
- Always have a backup plan (PIN code)
- Never store the actual fingerprint—only ask “Is this the owner?”
🔒 Secure Storage: The Invisible Vault
What Is It?
Imagine a treasure chest that becomes invisible and can only be opened by the castle owner. That’s Secure Storage!
Simple Comparison:
| Regular Storage | Secure Storage |
|---|---|
| Writing on paper | Writing in invisible ink |
| Anyone can read | Only you can read |
| Easy to steal | Encrypted & protected |
The Magic Tool: Keychain
npm install react-native-keychain
Hiding a Secret
import * as Keychain from
'react-native-keychain';
// Hide the treasure
async function saveSecret() {
await Keychain.setGenericPassword(
'username', // Key
'super_secret_123' // Value
);
console.log('Secret hidden!');
}
Finding the Secret
async function getSecret() {
const credentials =
await Keychain.getGenericPassword();
if (credentials) {
console.log('Found it!');
console.log(credentials.password);
} else {
console.log('No secret found');
}
}
Destroying the Secret
async function deleteSecret() {
await Keychain.resetGenericPassword();
console.log('Secret destroyed!');
}
🏆 What Goes in the Vault?
- ✅ API tokens (keys to other services)
- ✅ User passwords (never in plain text!)
- ✅ Encryption keys
- ❌ NOT large files or images
🛡️ Security Best Practices: The Knight’s Code
The 7 Sacred Rules
Every knight (developer) must follow these rules to protect the castle:
Rule 1: Never Trust User Input
// 🚫 BAD - Trusting blindly
const query = `SELECT * FROM users
WHERE name = '${userInput}'`;
// ✅ GOOD - Using safe methods
const query = `SELECT * FROM users
WHERE name = ?`;
// Pass userInput as parameter
Rule 2: Keep Secrets Out of Code
// 🚫 BAD - Secret in code
const API_KEY = "abc123secret";
// ✅ GOOD - Use environment config
import Config from 'react-native-config';
const API_KEY = Config.API_KEY;
Rule 3: Always Use HTTPS
// 🚫 BAD
fetch('http://api.example.com/data')
// ✅ GOOD
fetch('https://api.example.com/data')
Rule 4: Validate Everything
function validateEmail(email) {
const pattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return pattern.test(email);
}
// Use it!
if (!validateEmail(userEmail)) {
alert('Invalid email!');
return;
}
Rule 5: Set Token Expiration
graph TD A["Token Created"] --> B["Valid for 1 hour"] B --> C{Time Up?} C -->|No| D["Keep Using"] C -->|Yes| E["Must Login Again"]
Rule 6: Clear Sensitive Data
// When user logs out
async function logout() {
// Clear secure storage
await Keychain.resetGenericPassword();
// Clear app state
setUserData(null);
setToken(null);
console.log('All traces removed!');
}
Rule 7: Enable Certificate Pinning
This is like checking if a letter has the official royal seal:
// Trust only YOUR server
const sslPinning = {
certs: ['your-certificate']
};
📚 SQLite Basics: The Royal Library
What Is SQLite?
Imagine a tiny library that lives INSIDE your phone. It can store books (data) even when there’s no internet!
graph TD A["Your App"] --> B["SQLite Library"] B --> C["📖 Tables = Bookshelves"] C --> D["📄 Rows = Books"] D --> E["📝 Columns = Book Details"]
Why Use SQLite?
- 📴 Works offline
- ⚡ Super fast
- 💾 Stores lots of data
- 🆓 Completely free
Setting Up the Library
npm install react-native-sqlite-storage
Opening the Library Doors
import SQLite from
'react-native-sqlite-storage';
// Open/create database
const db = SQLite.openDatabase(
{ name: 'MyLibrary.db' },
() => console.log('Library open!'),
(err) => console.log('Error:', err)
);
Creating a Bookshelf (Table)
db.transaction((tx) => {
tx.executeSql(
`CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE,
age INTEGER
)`,
[],
() => console.log('Shelf ready!'),
(err) => console.log('Error:', err)
);
});
📋 Data Types in SQLite
| Type | What It Stores | Example |
|---|---|---|
| INTEGER | Whole numbers | 42, -7 |
| TEXT | Words & sentences | "Hello" |
| REAL | Decimal numbers | 3.14 |
| BLOB | Files & images | Binary data |
| NULL | Nothing/empty | null |
✏️ SQLite Operations: The Librarian’s Skills
A good librarian knows how to Add, Find, Update, and Remove books. These are called CRUD operations:
- Create (Add new)
- Read (Find & view)
- Update (Change)
- Delete (Remove)
📥 CREATE: Adding a New Book
function addUser(name, email, age) {
db.transaction((tx) => {
tx.executeSql(
`INSERT INTO users
(name, email, age)
VALUES (?, ?, ?)`,
[name, email, age],
() => console.log('User added!'),
(err) => console.log('Error:', err)
);
});
}
// Use it!
addUser('Alice', 'alice@mail.com', 25);
📖 READ: Finding Books
// Get ALL users
function getAllUsers() {
db.transaction((tx) => {
tx.executeSql(
'SELECT * FROM users',
[],
(tx, results) => {
const users = [];
for (let i = 0; i < results.rows.length; i++) {
users.push(results.rows.item(i));
}
console.log('Users:', users);
}
);
});
}
// Find ONE user by ID
function getUserById(id) {
db.transaction((tx) => {
tx.executeSql(
'SELECT * FROM users WHERE id = ?',
[id],
(tx, results) => {
if (results.rows.length > 0) {
console.log(results.rows.item(0));
}
}
);
});
}
✏️ UPDATE: Changing Book Details
function updateUserAge(id, newAge) {
db.transaction((tx) => {
tx.executeSql(
`UPDATE users
SET age = ?
WHERE id = ?`,
[newAge, id],
() => console.log('Age updated!'),
(err) => console.log('Error:', err)
);
});
}
// Birthday! Make Alice older
updateUserAge(1, 26);
🗑️ DELETE: Removing a Book
function deleteUser(id) {
db.transaction((tx) => {
tx.executeSql(
'DELETE FROM users WHERE id = ?',
[id],
() => console.log('User removed!'),
(err) => console.log('Error:', err)
);
});
}
// Goodbye user #5
deleteUser(5);
🔍 Advanced: Searching with Conditions
// Find users over 18
function getAdults() {
db.transaction((tx) => {
tx.executeSql(
'SELECT * FROM users WHERE age >= 18',
[],
(tx, results) => {
console.log('Found adults!');
}
);
});
}
// Search by name pattern
function searchByName(pattern) {
db.transaction((tx) => {
tx.executeSql(
`SELECT * FROM users
WHERE name LIKE ?`,
[`%${pattern}%`],
(tx, results) => {
console.log('Search results!');
}
);
});
}
🏁 The Complete Flow
Here’s how everything works together:
graph TD A["User Opens App"] --> B{Has Account?} B -->|No| C["Create Account"] C --> D["Save to SQLite"] D --> E["Store Token Securely"] B -->|Yes| F["Biometric Check"] F -->|Pass| G["Get Secure Token"] G --> H["Load Data from SQLite"] H --> I["🎉 App Ready!"] F -->|Fail| J["Show PIN Entry"]
🎓 Quick Summary
| Topic | What It Does | Key Tool |
|---|---|---|
| Biometrics | Verifies identity | react-native-biometrics |
| Secure Storage | Hides secrets | react-native-keychain |
| Best Practices | Prevents attacks | HTTPS, validation |
| SQLite Basics | Creates database | sqlite-storage |
| SQLite Ops | CRUD data | SQL commands |
🌟 You Did It!
You’ve learned how to:
- ✅ Use fingerprints to guard your app
- ✅ Hide secrets in an invisible vault
- ✅ Follow the knight’s code of security
- ✅ Build a local database library
- ✅ Add, find, change, and delete data
Your castle is now the SAFEST in the land! 🏰🛡️
Remember: Security is not a feature—it’s a mindset. Always think like a guard protecting precious treasures!
