content/blog/2020-08-29-php-auth-flow.org
188 lines · 6331 bytes
1#+date: <2020-08-29 Sat 00:00:00>
2#+title: Implementation Guide for PHP-Based User Authentication with MySQL Backend
3#+description: Comprehensive guide to developing a secure user login system in PHP utilizing MySQL database, including account creation, session management, and logout procedures.
4#+slug: php-auth-flow
5#+filetags: :php:authentication:mysql:
6
7* Introduction
8
9When creating websites that will allow users to create accounts, the developer
10always needs to consider the proper authentication flow for their app. For
11example, some developers will utilize an API for authentication, some will use
12OAuth, and some may just use their own simple database.
13
14For those using pre-built libraries, authentication may simply be a problem of
15copying and pasting the code from their library's documentation. For example,
16here's the code I use to authenticate users with the Tumblr OAuth API for my
17Tumblr client, Vox Populi:
18
19#+begin_src php
20// Start the session
21session_start();
22
23// Use my key/secret pair to create a new client connection
24$consumer_key = getenv('CONSUMER_KEY');
25$consumer_secret = getenv('CONSUMER_SECRET');
26$client = new Tumblr\API\Client($consumer_key, $consumer_secret);
27$requestHandler = $client->getRequestHandler();
28$requestHandler->setBaseUrl('https://www.tumblr.com/');
29
30// Check the session and cookies to see if the user is authenticated
31// Otherwise, send user to Tumblr authentication page and set tokens from Tumblr's response
32
33// Authenticate client
34$client = new Tumblr\API\Client(
35 $consumer_key,
36 $consumer_secret,
37 $token,
38 $token_secret
39);
40#+end_src
41
42However, developers creating authentication flows from scratch will need to
43think carefully about when to make sure a web page will check the user's
44authenticity.
45
46In this article, we're going to look at a simple authentication flow using a
47MySQL database and PHP.
48
49* Creating User Accounts
50
51The beginning to any type of user authentication is to create a user account.
52This process can take many formats, but the simplest is to accept user input
53from a form (e.g., username and password) and send it over to your database. For
54example, here's a snippet that shows how to get username and password parameters
55that would come when a user submits a form to your PHP script.
56
57*Note*: Ensure that your password column is large enough to hold the hashed
58value (at least 60 characters or longer).
59
60#+begin_src php
61// Get the values from the URL
62$username = $_POST['username'];
63$raw_password = $_POST['password'];
64
65// Hash password
66// password_hash() will create a random salt if one isn't provided, and this is generally the easiest and most secure approach.
67$password = password_hash($raw_password, PASSWORD_DEFAULT);
68
69// Save database details as variables
70$servername = "localhost";
71$username = "username";
72$password = "password";
73$dbname = "myDB";
74
75// Create connection to the database
76$conn = new mysqli($servername, $username, $password, $dbname);
77
78// Check connection
79if ($conn->connect_error) {
80 die("Connection failed: " . $conn->connect_error);
81}
82
83$sql = "INSERT INTO users (username, password)
84VALUES ('$username', '$password')";
85
86if ($conn->query($sql) === TRUE) {
87 echo "New record created successfully";
88} else {
89 echo "Error: " . $sql . "<br>" . $conn->error;
90}
91
92$conn->close();
93#+end_src
94
95** Validate Returning Users
96
97To be able to verify that a returning user has a valid username and password in
98your database is as simple as having users fill out a form and comparing their
99inputs to your database.
100
101#+begin_src php
102// Query the database for username and password
103// ...
104
105if(password_verify($password_input, $hashed_password)) {
106 // If the input password matched the hashed password in the database
107 // Do something, log the user in.
108}
109
110// Else, Redirect them back to the login page.
111...
112#+end_src
113
114* Storing Authentication State
115
116Once you've created the user's account, now you're ready to initialize the
117user's session. *You will need to do this on every page you load while the user
118is logged in.* To do so, simply enter the following code snippet:
119
120#+begin_src php
121session_start();
122#+end_src
123
124Once you've initialized the session, the next step is to store the session in a
125cookie so that you can access it later.
126
127#+begin_src php
128setcookie(session_name());
129#+end_src
130
131Now that the session name has been stored, you'll be able to check if there's an
132active session whenever you load a page.
133
134#+begin_src php
135if(isset(session_name())) {
136 // The session is active
137}
138#+end_src
139
140** Removing User Authentication
141
142The next logical step is to give your users the option to log out once they are
143done using your application. This can be tricky in PHP since a few of the
144standard ways do not always work.
145
146#+begin_src php
147// Initialize the session.
148// If you are using session_name("something"), don't forget it now!
149session_start();
150
151// Delete authentication cookies
152unset($_COOKIE[session_name()]);
153setcookie(session_name(), "", time() - 3600, "/logged-in/");
154unset($_COOKIE["PHPSESSID"]);
155setcookie("PHPSESSID", "", time() - 3600, "/logged-in/");
156
157// Unset all of the session variables.
158$_SESSION = array();
159session_unset();
160
161// If it's desired to kill the session, also delete the session cookie.
162// Note: This will destroy the session, and not just the session data!
163if (ini_get("session.use_cookies")) {
164 $params = session_get_cookie_params();
165 setcookie(session_name(), '', time() - 42000,
166 $params["path"], $params["domain"],
167 $params["secure"], $params["httponly"]
168 );
169}
170
171// Finally, destroy the session.
172session_destroy();
173session_write_close();
174
175// Go back to sign-in page
176header('Location: https://example.com/logged-out/');
177die();
178#+end_src
179
180* Wrapping Up
181
182Now you should be ready to begin your authentication programming with PHP. You
183can create user accounts, create sessions for users across different pages of
184your site, and then destroy the user data when they're ready to leave.
185
186For more information on this subject, I recommend reading the [[https://www.php.net/][PHP Documentation]].
187Specifically, you may want to look at [[https://www.php.net/manual/en/features.http-auth.php][HTTP Authentication with PHP]], [[https://www.php.net/manual/en/book.session.php][session
188handling]], and [[https://www.php.net/manual/en/function.hash.php][hash]].