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