Skip to content

Commit dce438c

Browse files
committed
feat: add security docs
1 parent 23f7f2a commit dce438c

File tree

6 files changed

+733
-44
lines changed

6 files changed

+733
-44
lines changed

.vitepress/config/sidebar.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ const sidebar = [
1010
{ text: 'Using Docker', link: '/docs/docker' },
1111
{ text: 'Migration Guide', link: '/docs/migrating' },
1212
{ text: 'Functional Mode', link: '/docs/config/functional-mode' },
13-
{ text: 'Leaf + MVC', link: '/docs/mvc/' },
1413
{ text: 'Modules', link: '/docs/modules' },
1514
],
1615
},
@@ -74,7 +73,7 @@ const sidebar = [
7473
{ text: 'Debugging', link: '/docs/config/debugging' },
7574
// { text: 'Leaf Devtools', link: '/docs/utils/devtools' },
7675
// { text: 'Deployment', link: '/docs/config/deployment' },
77-
{ text: 'Testing', link: '/docs/utils/testing' },
76+
{ text: 'Testing/Linting', link: '/docs/utils/testing' },
7877
],
7978
},
8079
{
@@ -116,7 +115,7 @@ const sidebar = [
116115
{ text: 'Validation', link: '/docs/data/validation' },
117116
{ text: 'CSRF Protection', link: '/docs/security/csrf' },
118117
{ text: 'Leaf Password', link: '/docs/data/encryption' },
119-
{ text: 'Leaf Anchor', link: '/docs/security/anchor' },
118+
{ text: 'General Security', link: '/docs/security/anchor' },
120119
],
121120
},
122121
{
@@ -153,6 +152,7 @@ const sidebar = [
153152
// collapsible: true,
154153
// collapsed: true,
155154
items: [
155+
{ text: 'Leaf + MVC', link: '/docs/mvc/' },
156156
{ text: 'MVC Config', link: '/docs/config/mvc' },
157157
{ text: 'Controllers', link: '/docs/mvc/controllers' },
158158
{ text: 'Views', link: '/docs/frontend/mvc' },

src/docs/auth/protected-routes.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,141 @@
11
# Protected Routes
2+
3+
<!-- markdownlint-disable no-inline-html -->
4+
5+
There are usually parts of your application that you want to be available to only logged in users or guest users. That's where protected routes come in. Protected routes are setup to allow users with a certain authentication status to access them.
6+
7+
## The `user` method
8+
9+
The `user()` method is a way to check if a user is logged in. It returns the currently logged in user if an authenticated user is found and `null` if a user is not logged in.
10+
11+
This works for both session and token based authentication. In case of token based authentication, Leaf Auth will also check if the token is valid. If it is, the user is returned, if not, `null` is returned. You can get the reason for the authentication failure by calling the `errors()` method.
12+
13+
```php{1,7}
14+
$user = auth()->user();
15+
16+
if ($user) {
17+
// user is logged in
18+
} else {
19+
// user is not logged in
20+
$errors = auth()->errors();
21+
}
22+
```
23+
24+
Using this method, you can easily protect your routes by checking if a user is logged in. If a user is not logged in, you can redirect them to the login page or return a 401 error. Here's an example:
25+
26+
```php
27+
app()->get('/protected', function () {
28+
$user = auth()->user();
29+
30+
if ($user) {
31+
// user is logged in
32+
} else {
33+
// user is not logged in
34+
response()->redirect('/login');
35+
}
36+
});
37+
```
38+
39+
For API routes, you can return a 401 error if a user is not logged in.
40+
41+
```php
42+
app()->get('/protected', function () {
43+
$user = auth()->user();
44+
45+
if ($user) {
46+
// user is logged in
47+
} else {
48+
// user is not logged in
49+
response()->json([
50+
"error" => "Unauthorized",
51+
"data" => auth()->errors(),
52+
], 401);
53+
}
54+
});
55+
```
56+
57+
## The `id` method
58+
59+
The id() method lets you get the ID of the user who is currently logged in. This is helpful when you need to work with the user's ID in your app. If no user is logged in, the method returns `null` instead.
60+
61+
```php
62+
app()->get('/protected', function () {
63+
$id = auth()->id();
64+
65+
if ($id) {
66+
// user is logged in
67+
} else {
68+
// user is not logged in
69+
response()->redirect('/login');
70+
}
71+
});
72+
```
73+
74+
## Using Middleware
75+
76+
Leaf Auth also provides a middleware that you can use to protect your routes. The `auth` middleware checks if a user is logged in and allows you to set a callback function to run if a user is not logged in.
77+
78+
```php
79+
auth()->middleware('auth.required', function () {
80+
response()->redirect('/login');
81+
});
82+
```
83+
84+
Once you have defined a callback for the middleware, you can use it in your routes like this:
85+
86+
```php
87+
app()->get('/protected', ['middleware' => 'auth.required', function () {
88+
// this route is protected
89+
}]);
90+
91+
// or on a route group
92+
app()->group('/protected', ['middleware' => 'auth.required', function () {
93+
app()->get('/route', function () {
94+
// this route is protected
95+
});
96+
}]);
97+
```
98+
99+
If you use this method, the middleware will run before the route is executed. If the user is not logged in, the callback function you defined will be executed. This means you can remove the check for a logged in user from your route handler.
100+
101+
```php
102+
app()->get('/protected', ['auth.required', function () {
103+
$user = auth()->user();
104+
105+
// no need to check if user is logged in
106+
}]);
107+
```
108+
109+
## Protected Guest Routes
110+
111+
You can also protect routes that should only be accessible to guest users. This is useful for routes like the login and register routes. You can use the `auth.guest` middleware to protect these routes.
112+
113+
```php
114+
auth()->middleware('auth.guest', function () {
115+
response()->redirect('/dashboard');
116+
});
117+
```
118+
119+
You can then use this middleware on your guest routes like this:
120+
121+
```php
122+
app()->get('/login', ['middleware' => 'auth.guest', function () {
123+
// this route is only accessible to guest users
124+
}]);
125+
```
126+
127+
This middleware will run before the route is executed. If a user is logged in, the callback function you defined will be executed. This means you can remove the check for a guest user from your route handler.
128+
129+
```php
130+
app()->get('/login', ['auth.guest', function () {
131+
// no need to check if the user is a guest
132+
}]);
133+
```
134+
135+
## Session Guards <Badge type="danger" text="DEPRECATED" />
136+
137+
The previous version of Leaf Auth had a feature called session guards. This feature has been deprecated in the latest version of Leaf Auth. If you were using session guards in your app, you can switch to the new middleware system to protect your routes.
138+
139+
The middleware system is more flexible and allows you to define more complex authentication logic using the middleware callback functions.
140+
141+
You can also use the middleware system to protect routes for both logged in and guest users, which is essentially what session guards were used for.

src/docs/data/encryption.md

Lines changed: 129 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,129 @@
1-
# Data Encryption
1+
# Password Encryption
2+
3+
Password encoding and verification are one of the most important parts of any application. This usually involves a lot of security concerns and can be a pain to implement. Leaf makes this process a lot easier with the password helper.
4+
5+
Before you go on, Leaf already has a [full authentication system](/docs/auth/) that comes with simple authentication, session/token management and so much more. Your use case may already be covered by Leaf Auth, so be sure to check that first.
6+
7+
## Setting up
8+
9+
You can install the password helper using the Leaf CLI:
10+
11+
::: code-group
12+
13+
```bash:no-line-numbers [Leaf CLI]
14+
leaf install password
15+
```
16+
17+
```bash:no-line-numbers [Composer]
18+
composer require leafs/password
19+
```
20+
21+
:::
22+
23+
From there, you can use any of the Password methods.
24+
25+
## spice
26+
27+
Just as the name implies, spice adds a little "spice" to users' passwords. They help make even weak passwords a pain for systems to crack by chaining additional characters to the password before encoding or decoding.
28+
29+
A weak password like `password123` when spiced can become `@X$p0#f&password123` without pressing the user to stick to "Your password should contain numbers, letters and ...".
30+
31+
The `spice` method can both be used to set and get the password spice.
32+
33+
This sets the password spice which will be encrypted based on the hash you set:
34+
35+
```php
36+
use Leaf\Helpers\Password;
37+
38+
Password::spice('#@%7g0!&');
39+
```
40+
41+
**The next examples will assume you've added `use Leaf\Helpers\Password`**
42+
43+
This returns the password spice:
44+
45+
```php
46+
$spice = Password::spice();
47+
```
48+
49+
**Spices are automaticatically chained to all password related stuff, so after setting your spice, you don't need to worry about it.**
50+
51+
## `Password::hash()`
52+
53+
This method basically creates a password hash. It takes in 3 parameters:
54+
55+
- The password to encrypt
56+
- The encryption hash (optional)
57+
- An array of options for the password hash (optional)
58+
59+
```php
60+
$hash = Password::hash('USER_PASSWORD', Password::BCRYPT);
61+
```
62+
63+
The default encryption hash used if none is provided is `Password::DEFAULT` which is `PASSWORD_DEFAULT`.
64+
65+
Also, the most commonly used hashes, BCRYPT and Argon2 are accessible on the Password Helper object as `Password::BCRYPT` and `Password::ARGON2`.
66+
67+
The final options array differs based on the hash you're using. See the [password algorithm constants](https://secure.php.net/manual/en/password.constants.php) for documentation on the supported options for each algorithm.
68+
69+
## `Password::verify()`
70+
71+
Verifying a user’s password has been made really simple thanks to the `verify()` method. Simply pass the plaintext password supplied by the user and compare it to the stored hash, like so:
72+
73+
```php
74+
if (Password::verify($password, $hashedPassword)) {
75+
// handle user login here
76+
}
77+
```
78+
79+
verify returns true on success and false on failure.
80+
81+
`$hashedPassword` in the following examples refers to the stored hashed password.
82+
83+
## argon 2
84+
85+
Argon2 is one encryption method heavily used by a lot of developers. Although creating and verifying passwords with argon2 is nothing difficult, Leaf makes it even simpler with methods targetting only argon.
86+
87+
### `argon2()`
88+
89+
This is a simply method used to create an Argon2 hash for your password. It takes in 2 parameters, the password to encrypt and the options for the hashing.
90+
91+
```php
92+
$hash = Password::argon2($password, $options);
93+
```
94+
95+
The options parameter is optional, but in case you want to set your own options, see the [password algorithm constants](https://secure.php.net/manual/en/password.constants.php) for documentation on the supported options for Argon2.
96+
97+
### `argon2Verify()`
98+
99+
This method simply checks the validity of an Argon2 hash.
100+
101+
```php
102+
if (Password::argon2Verify($password, $hashedPassword)) {
103+
// handle user login here
104+
}
105+
```
106+
107+
## BCRYPT
108+
109+
BCRYPT is another hash used widely by a lot of developers, especially since support with BCRYPT has been on longer than other hashes like Argon 2. We just make hashing with BCRYPT even easier than it currently is.
110+
111+
### `bcrypt()`
112+
113+
This is a simply method used to create an BCRYPT hash for your password. It takes in 2 parameters, the password to encrypt and the options for the hashing.
114+
115+
```php
116+
$hash = Password::bcrypt($password, $options);
117+
```
118+
119+
The options parameter is optional, but in case you want to set your own options, see the [password algorithm constants](https://secure.php.net/manual/en/password.constants.php) for documentation on the supported options for BCRYPT.
120+
121+
### `brcyptVerify()`
122+
123+
This method simply checks the validity of an BCRYPT hash.
124+
125+
```php
126+
if (Password::brcyptVerify($password, $hashedPassword)) {
127+
// handle user login here
128+
}
129+
```

0 commit comments

Comments
 (0)