Class Checkpoint

Making Parkwood Vale · Part 9 of 13

Part 8

Send email from PHP with PHPMailer and Gmail, then build the full forgot password reset.

We get email working so new users get a welcome message, then build the forgot password process from the reset email through to a new password. In this part: 0:00 Why mail did not send, and the plan 1:29 A test Gmail account and its SMTP settings 5:47 Changing UwAmp's PHP mail settings 9:14 Downloading PHPMailer from GitHub 11:34 Sending the welcome email when someone registers 17:20 Fixing PHPMailer errors 19:44 Gmail sign in: ports, 2-step verification and an app password 25:00 The welcome email arrives 28:03 The forgot password form and its handler 30:05 Making a reset token and emailing the link 42:57 Checking the token and asking for a new password 53:45 Saving the new password and testing the whole reset Software: Adobe Dreamweaver, UwAmp, PHPMailer, Gmail, HeidiSQL, PHP.
Transcript
  1. Welcome back. So in our previous sessions then we have set up our server, we have
  2. created our database and we started creating our register, forgot password and login
  3. functions.
  4. We parked the forgot password function because the mail side of that wasn't working.
  5. The reason behind it is some settings in the back end of UwAmp need changing.
  6. The reason I didn't come up against that issue when I originally developed Parkwood
  7. Vale is that I used industry standard hosted web server
  8. technology, which I've been running personally for the last five years or so.
  9. So there's a few little different discrepancies within it.
  10. But I'm trying to base this tutorial series around something simple and easy you can
  11. implement within a school.
  12. with that in mind then what we're going to have to do within this session is fix the
  13. SMTP issues, register for a dummy email address because you cannot provide
  14. the WJEC with credentials linked to your students school email address or personal
  15. email addresses so they need a throwaway email address that could be used if they
  16. are using their mail functions,
  17. Set up the SMTP side of things to connect via PHP and fire off emails automatically
  18. when a user registers or clicks on forgot password and enters the correct details.
  19. Okay, let's get into it.
  20. Okay, so here I am back in my student desktop then and I'm going to start off by
  21. registering
  22. dummy email address. Now I've opened up my stuff edge here and what I'm gonna do is
  23. just quickly jump into incognito mode or in private browsing mode because I don't
  24. want any preset cookies upsetting what we're trying to do today.
  25. I'm gonna go to mail.google.com and it's gonna come up it's not gonna know who I am
  26. because I haven't got any of those cookies in place so I want to create an account.
  27. It is gonna be for personal use and I'm just gonna fill in my basic
  28. jobs going on from there then you can put in your basic information now
  29. realistically your students should be over the age of 16 so they should be able to
  30. set up their own email addresses and I'm gonna go in I'm gonna say that I'm male and
  31. go on to the next step how do I want to sign in this can be a bit of a tricky
  32. situation to put in place what I would suggest would be your center number
  33. underscore your candidate number so six eight five six seven
  34. underscore one two three four or something similar like that now they're gonna have
  35. to be able to remember this throughout the whole of this project so making sure it's
  36. something relevant to them is very important and also putting it in as your
  37. candidate number and your center number does tie it back to the WJEC so they know
  38. whose is what and what's going on.
  39. I'm gonna go in though just to make it easier for me and call it parkwoodveildemo at
  40. gmail.com because I need to remember this as well.
  41. Password then it's gonna have to be something semi-complex because it's following
  42. Google's password rules
  43. and I'm going to click on.
  44. It does help if you can type the same thing twice.
  45. Who would have thought the longest part of that would be me typing in a password?
  46. Anyway, recovery email address, I can just skip that stage, skip that stage there
  47. and click next.
  48. I express personalization, I'm not that bothered about things.
  49. I'm just going to scroll through and confirm, agree to the terms and conditions.
  50. This is just purely for my coursework, a sync call for me to send emails from.
  51. I don't have to worry about marketing or anything like that because it's going to
  52. send about 10 emails at most, probably from what I've set up.
  53. Now the way that Google works, yes, continue with smart features,
  54. is limited version. Let's just get through it.
  55. Thank you. We do need to make one more change on top of all of this as we
  56. go through. I need to go into the settings section up here.
  57. I need to see all settings and I need to go to pop them forward in and I need to
  58. enable
  59. iMap and put that in place so that's all set up and save changes otherwise it won't
  60. allow me to use my SMTP and then next what we need to do is find out the SMTP
  61. details for Google just to make sure we're using the correct addresses so I'm going
  62. to put it in here just simply Google SMTP and see what we come back with lots of
  63. different elements we're going to go for the Google developers article which should
  64. take us directly through how SMTP protocol should be accessed and what we should
  65. use. So it says SMTP ports here incoming mail is there.
  66. SMTP is just simply below it and it's got the different elements in place there we
  67. need. Perfect. So what I'm going to do is I'm going to jump into my
  68. UwAmp, launch UwAmp and this is where I need to start making
  69. settings. There it is, here's my UwAmp client and the settings I'm going to be
  70. changing are all based around this Apache web server or this PHP element sorry
  71. another Apache web server the PHP element.
  72. I'm gonna click on this little tiny file icon at the very end here that's gonna
  73. bring up a text file with
  74. absolutely every controllable element to do with PHP in place.
  75. What I'm going to try and do, let's see if it'll allow me, is zoom right in so you
  76. can see what I'm doing. You should be able to see this nice and clearly now because
  77. it's not very much on the way of lines we need to change.
  78. I'm going to use the control and F function to find mail.
  79. Now it's actually the second element through and what we're looking for are these
  80. settings here which say mail function and it's got SMTP localhost, SMTP
  81. port 25. We don't want to keep those as standard.
  82. Our local host doesn't have our mail server to be able to send anything and we are
  83. not connecting via port 25. What we're going to do instead is we're going to SMTP
  84. connect to gmail.com. We're going to copy that into
  85. localhost and paste it. And I want to connect through ports.
  86. Let's try 465 first and just see if that one works as we expect it to.
  87. I'm gonna change that to 465
  88. Now there are no line numbers I can specifically tell you for this or anything or
  89. how to search for it Except for the fact we're working in that mail function We are
  90. changing the SMTP to SMTP.gmail.com or whatever equivalent you use so if you decide
  91. that you're gonna use Outlook you use this there and Port set up 465 is pretty
  92. standard for SMTP Now the rest of these elements here, you can see these semicolons
  93. in place. What they actually mean is that that element is commented out, so it's not
  94. actually being actioned in any way.
  95. The only male functions that are being actioned are these two that don't start with
  96. that semicolon. If I save this then,
  97. I close this,
  98. let's minimize that for a second then, and I'm going to stop my server
  99. and
  100. restart my server so that those settings take effect.
  101. I'm going to go back into Adobe Dreamweaver.
  102. I should have my site as it was when we last set it up.
  103. So let's close those down and very quickly let's open up our register application
  104. here and that's where they put in all their details that's perfectly fine i'm going
  105. to open up the sign up here and what i want to do is
  106. i've inserted their details there that's where they've signed up this is where i'm
  107. going to start putting in some mail functions now php does have its own mail
  108. library built in but that will not work for us using WAMP or UwAmp or anything like
  109. that we have to use an outside library there's a very detailed very good outside
  110. library that we're gonna plug into which is very well documented which is PHPMailer
  111. when I search for PHPMailer then there's going to be lots of different links to it
  112. the top one we're looking for the github link so you could put in github there
  113. because that's who's developed PHPMailer is the most supported version of php
  114. mailer and that's what we're looking for now as i go through then you'll have some
  115. instructions it has all the details about it it shows you how to use it using docker
  116. which we're not going to be doing and how to download it as a zip and use it in
  117. standard form which is what we will be doing so i'm going to download the zip file
  118. and here's my PHPMailer file i'm going to open it up inside there we have
  119. PHPMailer and all these different elements so you've got PHPMailer inside there
  120. PHPMailer we're looking for in here should be a PHPMailer file
  121. nope PHPMailer source PHPMailer is there so we're going to just slightly
  122. change perhaps how one or two of these different elements work what we're going to
  123. do is going to take this master PHPMailer file here I'm going to just show
  124. it in a folder and I'm going to extract it using 7-zip to extract the files
  125. to
  126. USB UwAmp into the WWW folder and I can see I did this earlier just check it does
  127. work let's just drop that there now
  128. in my UwAmp folder in the WWW folder you'll see I've got PHP mail and PHP
  129. mail and master that's the one I've just exported that's the one I checked the other
  130. day to make sure it was working delete that one and let's
  131. just rename this one and remove the word master
  132. so we have PHPMailer and we want to remove master from there as well so that's all
  133. in place so we have PHPMailer set up with there and it should all go
  134. through as we expected to we got PHPMailer source
  135. is there and all set up
  136. let's close that down then close that down up
  137. in fact actually PHPMailer
  138. bring that back up and what i'm going to do is i'm going to
  139. use these elements here so i'm going to say copy these five lines of code
  140. into my php session start the session place those elements there and it's got the
  141. path to these setups well the path to it in this occasion my
  142. require is going to be going to
  143. phpmailer source and accept execution
  144. and that should have all of that in place now because i copied that into my ump
  145. folder it's not actually in my local folder so let me just rectify that a second i'm
  146. going to copy it from there into my documents into my WWW
  147. folder which is just here and paste it there and now I should be able to
  148. refresh this and
  149. I'll see PHPMailer is there so it's all coming together it's all in place what I'm
  150. gonna do is just simply put a full stop in these elements here and that should set
  151. that up now
  152. has its own classification for how we send emails.
  153. So in this here then they put it in a try catch as a bit of error detection.
  154. What it's saying is set up the variable mail as a PHPMailer, set
  155. it up as SMTP and here are our host details.
  156. We're going to go through and add some people to it.
  157. We can add attachments if we wanted to.
  158. We're going to give it some content and then we're going to send that message at the
  159. very end there. So I'm just going to take these lines of code here including their
  160. comments and I'm going to copy them and after my
  161. user has been created I'm going to paste them there.
  162. To start off with then I need to correct my SMTP that's going to be the same SMTP as
  163. I used earlier to get into
  164. my Google SMTP so it was just smtp.gmail.com.
  165. Auth is true, the username password are the usernames and passwords set for
  166. my email addresses that I've just set up here.
  167. So in here then I'm going to put in pwvdemo
  168. at gmail.com
  169. The password then was
  170. parkwoodvale123. And the port would be
  171. 465.
  172. It's sent from pwv at gmail.com.
  173. Now, it's really important that they match because Google is going to look at that
  174. and say, this is our connected user.
  175. This is who they're trying to send an email as.
  176. If they're different, it's going to look suspicious and they won't send that email.
  177. I can just put in here Parkwood Vale.
  178. Address that is being sent to.
  179. Now we should have that in our post email element at the top here so I can take that
  180. address and send it to there.
  181. The for name and surnames again we have at the top here from where the
  182. user has provided us with their information and And all I'm going to do is
  183. just concatenate those two elements, put those together, and that will put that in
  184. place. So it's using the details directly from our post to insert it there.
  185. We don't have any additional elements.
  186. We could add in addresses, who they should reply to, any CC or BCC elements, but I'm
  187. not interested in those. So I'm going to remove those out.
  188. We aren't including any attachments.
  189. This is a welcome to the library email.
  190. We're not attaching files with it.
  191. HTML is true, yes, subject, I'm going to just say simply, welcome
  192. to Parkwood Vale
  193. Library.
  194. Body, I'm going to repeat that just to save some time.
  195. And the alt body, I'm not going to bother with at this moment.
  196. Now what that should do is set up and send my email address,
  197. email to that user.
  198. Logging is set up here. So what I can do while I'm testing and putting this in
  199. place, if I go back to here, is if I do wrap this in a try catch, if we have any
  200. errors, it will tell me what the error is.
  201. So let's grab that catch there.
  202. just drop the catch at the end here and we have echo the message can't be sent and
  203. then the details as to why the message can't be sent so there's my sign up element
  204. there if i look at this that's already gone up i don't need to worry about that my
  205. config's in place i'm working on the sign up function let's not do the same mistake
  206. last time and let's put that in place and let's go through and see if i'm getting an
  207. email now what i can do is open up my standard where browser here go to
  208. and just continue and here it is on my account then I'm going to
  209. register because that's the function I want to look at my name is James Jones it's
  210. going to cpd mrjjones.co.uk that's my cpd email address and password here I'm going
  211. to put in password one two three
  212. now if everything has worked correctly i should get an email to this address that
  213. will allow me to see what it looks like and see that it has come through so
  214. submit that and required fail to open could not find that
  215. online sick could not find that there so it's having issues finding these PHPMailer
  216. elements.
  217. PHPMailer, of course, I put it in PHPMailer again.
  218. So there's two PHPMailer elements there.
  219. So let me just copy that.
  220. Paste, paste, paste. So now it's going to PHPMailer, then PHPMailer, then it's
  221. going into the source folder and it can find what it's looking for.
  222. So let's save that. Sign up. Let's put that up.
  223. and hopefully just refresh this page and resubmit that details.
  224. Class MTP not found in line 43.
  225. Okay, let's just try it without the logging a second then.
  226. Save that.
  227. Put it.
  228. and refresh it.
  229. And find variable line 42.
  230. I know why we haven't set up that mail is part of
  231. phpmail.
  232. Yup, I forgot to include that so that it knew what mail was and that should now also
  233. pick up and include those elements as well.
  234. try catch back in place and let's put that up so all i forgot to do was i forgot to
  235. include mail is a new type of PHPMailer so that it knows what mail is
  236. still doesn't like that smtp element okay let's just comment that out for a second
  237. put that and refresh again.
  238. Line 44 this time, what's I not happy with?
  239. Mail could not be sent. There we go.
  240. Could not authenticate.
  241. Error incident.
  242. Okay. So I've got a duplicate entry for me.
  243. And it's saying SMTP could not authenticate the user on my SMTP side of things.
  244. So we've got 465 there.
  245. What if we were to change the port to 587
  246. and see if that works?
  247. 587. I know it's not going to like me because I'm doing this a second time, but
  248. let's try that again.
  249. Still telling me it can't authenticate.
  250. I need to open up Heidi for a second.
  251. HeidiSQL.
  252. and let's jump into users and just delete that user a
  253. second there we go
  254. okay so looking at that it seems to done all of that but has it sent me an email
  255. That would be a true test. Let's have a look.
  256. I'm going to open up Outlook.
  257. And just load it to see if anything has come through.
  258. But I can tell you now my watch hasn't vibrated, so it's not looking very promising.
  259. And nothing has come through at all.
  260. And nothing's even gone into junk for that email address.
  261. So one reason why this might be happening and giving us an error is Google
  262. doesn't like anything web-based that could possibly scam somebody, cause
  263. offense, cause any sort of malicious damage or anything like that.
  264. So they don't allow what they consider to be less secure email accounts to send
  265. messages, less secure clients to be able to do different elements.
  266. So what I'm going to do is I'm
  267. for Google. I'm going to go to the security section and it used to be quite simple.
  268. We could scroll down to this section here that says allow less secure access but as
  269. you can see this is no longer available.
  270. What we have to do instead is we need to enable two-factor authentication.
  271. And once that's enabled, what I can do is go into my two-step
  272. authentication and I can set up an app
  273. password.
  274. password for a mail function that I can do from other
  275. and I'm gonna say P would Parkwood Vale
  276. email and I'm gonna generate that password now Google has
  277. generated that password for me as opposed to me coming up with it I can copy that
  278. and click on done and when I go into my authentication by paste
  279. that password there that should now authenticate me through.
  280. Now let's have a look and see if that has worked.
  281. So I go back to the account page I want to register I'm gonna put in my details
  282. and
  283. I'm gonna submit that there.
  284. Now it's telling me that it still can't authenticate me.
  285. I know why it can't authenticate me.
  286. There we go. Let's try that one again.
  287. Refresh this page. Continue.
  288. Could not connect to SMTP host.
  289. Failed to connect to SMTP server.
  290. Connection error.
  291. Okay, so that's connected on 587.
  292. But if you remember, when I was in PHP in here, I was in the mail function
  293. I actually set it to 465. Let's zoom in again
  294. so let's change that to 587 so it matches save it
  295. close it and that's automatically going to stop and
  296. restart my element here now running perfectly fine and let's
  297. refresh it
  298. Password 123.
  299. Password 123. Submit.
  300. Message could not be sent. Could not connect to SMTP host.
  301. Just revalidating all of these elements turned on brilliant.
  302. Okay.
  303. Nothing's still in my sent element there.
  304. Google SMTP
  305. That hasn't changed. Okay, authenticated the 587.
  306. enable implicit DLS connection, TCP port,
  307. SMTP secure to PHPMailer.
  308. Okay, let's give that a try then, which is basically changing the type of
  309. encryption within our setup. Setup.
  310. Okay. No errors this time around.
  311. Did I get an email?
  312. I did.
  313. If I drag this over from my other screen, you should see it.
  314. I now have a Parkwood Vale email from Parkwood Vale demo to me with Welcome to
  315. Parkwood Vale Library. So after all of those settings, and I will put together a bit
  316. more of a guide rather than just this video to it, because there was quite a lot we
  317. had to go through to get to this stage.
  318. We are able to send emails. So every time a user registers, if
  319. it registers the user, it will go through and send them that email to say,
  320. welcome to our library system.
  321. we can go back now to our forgot user well forgot password section and get that
  322. coded up so that's working as well and have it reset our passwords i'm going to
  323. pause a second have a quick drink and then we'll come back and get that done
  324. okay so in this part then we're going to create our password reset functionality
  325. and let's dive right into it as you can see i have a forgot password page
  326. now all i've done there is right click create a new file called it forgot password
  327. and actually stole 90 of the code for our login
  328. I start with my session. I include the header PHP section so I can see that.
  329. I don't want to do that part. I want to zoom in.
  330. There you go. I've got my slider gallery and as I come down I've got my span
  331. for my sign-in error. Still called sign-in error on this section at the moment.
  332. I've got my form that this time around goes to the password reset page rather
  333. than my login or sign-in page.
  334. but this time around the only thing I'm actually taking is their email address
  335. called email and I've got my submit button.
  336. I've got down the bottom then the same stuff, the forgot password, not a member of
  337. register, all the same usual elements that were on that login page.
  338. Just copy and pasted it over and removed some of the elements that weren't really
  339. relevant. If I load it, so account and I go to forgot password
  340. you can see here how it looks.
  341. So from there then what we next need to do is capture the email address that they
  342. send to us. We need to check if it's in our database and if it is in our database we
  343. need to
  344. give it a unique reference that they can use and reset their password.
  345. To do all of that I need to start with a password reset page.
  346. So I'm going to go into new
  347. reset and again dot PHP because everything we're doing is a PHP file.
  348. In my password reset I don't need any of this but I do want to start my PHP tags.
  349. As always my next step should be my session and I want to start my session
  350. in place there and I am going to be including
  351. the connection to my config. So I want to include and just simply let's check
  352. these in place. It is config forward slash connection dot
  353. PHP. So that it has access to that setup and that in place there.
  354. As I'm going forward with this then, I am going to be using some of the mail
  355. functionality we've just added to our register function.
  356. So I'm going to take it directly from my sign in page.
  357. Nope, sign up page. Sorry, my bad.
  358. I'm going to use these elements here.
  359. I'm going to copy them. I'm going to paste them over.
  360. Now it doesn't matter if they're above or below the include, it shouldn't impact on
  361. how it runs.
  362. Let's zoom that in a bit so you can see what I've done so far.
  363. just like with my sign in page because a lot of the functionality is going to be
  364. similar to that i am going to go in i'm going to grab my error
  365. array setup to see if there are any errors with my email field and say that
  366. it can't be empty now i'm not going to be posting passwords so i don't need to worry
  367. about that but i will take my if else here my gatekeeper to my error to
  368. say that
  369. send them back to this time instead of the login page they're going back to the
  370. forgot password page and that's put
  371. that in place now I'm on to this section here this next section and a lot of it will
  372. again be very similar so I'm just going to very quickly just grab the whole of that
  373. file actually and we'll edit it as we go along so we still want to
  374. select email but not for name and
  375. this time from our users table where the email is equal to our email address but we
  376. don't need to worry about password this time around so all we've got is a very
  377. simple select to see if they exist in our database we're going to get the results in
  378. our query here and if the number of rows is equal to one then we're going to proceed
  379. to this section here i'll come back to what we're doing in this section here for a
  380. second i just want to address this bottom section we are no longer going to be doing
  381. an else here because we always wanted to return back to our same
  382. location our location is going to be our forgot password location and our
  383. message is just going to be slightly different it's gonna say if you have an account
  384. you will receive
  385. a reset email
  386. so we're not guaranteeing that everyone's email we're not saying that if you don't
  387. get a reset email you don't have an account or if you do have any we're just saying
  388. that if you exist we're going to send you one now inside of this then inside our if
  389. this is where it becomes really important we don't need to worry about fetching rows
  390. or anything like that we can get rid of this section here we will be putting in
  391. place our
  392. email section so i'm going to go back to our sign uh our register section which is
  393. our sign up and I'm just going to take my PHPMailer and the whole of
  394. this try catch element, copy it into here and paste it.
  395. So this is the part we set up in the first part of this video where we had in
  396. place PHPMailer is true, our SMTP, our host is Gmail, our
  397. email address and our password based on our app password set up earlier in this
  398. video. Our port is correct,
  399. but our address now is missing these details.
  400. We could pull these details from our select here and loop through them.
  401. We don't really need them. If I just went like that, it would send an email to that
  402. recipient and their email client will call them whatever it naturally calls them.
  403. So I can remove that entirely.
  404. Now it is a HTML email. The subject this time would be Parkwood Vale Library and I'm
  405. going to say password reset and the body
  406. is going to be completely different.
  407. Now this is where we're going to be including some information about how it's set up
  408. and how it's put together and what they need to do to get to the next stage to reset
  409. their password.
  410. I'll come on to that in two minutes time.
  411. That's all set up here. Let's just get this indentation fixed so it looks nice and
  412. neat and it's a bit easier to read.
  413. I don't need this on the side here so let's minimize it and there we go you've got
  414. the more detailed view there.
  415. So what we've said is if they have an account send them an email resetting their
  416. password but at the moment we haven't actually done anything to reset their
  417. password. We need to first of all set their password to something that we know
  418. so that we can tell them what it is
  419. function within SQL and we're going to update our users table
  420. and we're going to be setting our password value to
  421. something I'll explain what in two seconds time where our email
  422. value is equal to and this is where we're going to put back in place their email
  423. address as we did previously so that's that function there.
  424. I need to finish it with that tag and and comment it.
  425. Now just like we did when we were setting up our register we need to execute that
  426. email function and make sure that we're actually sending it.
  427. So I'm going to do connection for my MySQL database connection.
  428. I want to present it with a query and it is simply going to be my SQL
  429. query and put that in place. with the dollar sign so that it knows we're talking
  430. about that variable there. So that's going to perform that query then.
  431. So the last part is filling in what's going to go in here.
  432. Now before we perform that, I'm going to save it as a code because it's going to
  433. be a reset code for our password.
  434. And I'm going to use the hash function again, like we did with our password so that
  435. if it is encrypted, we don't know it, neither do they.
  436. and we're actually going to cheat ever so slightly.
  437. We're going to use a hashing algorithm called
  438. CRC32 which provides us with an 8-bit code and it's going to be using
  439. our post email address.
  440. Now again we talked about this briefly last time we're going to talk about it again.
  441. we want security to be the height of all of this if I did that and just did post CRC
  442. you could go on to the internet let's go into this one here and let's go on to
  443. CRC 32 generator
  444. and if I open this up we have a CRC generator where we can choose which style we
  445. want we want CRC32, and if I put in place here, cpd.at
  446. mrjjones.co.uk, I click on CRC32,
  447. it's going to give me back my answer when I come through to export it.
  448. There are lots of different ways in which we can generate our CRC32 codes.
  449. We can also decode CRC32 quite easily.
  450. but if we were to include just a very subtle change to it and we put the time
  451. function in place every time we do it it would kick the current timestamp from the
  452. server and apply that as a salt which would give us a unique code every single time
  453. increasing the complexity of the hashing algorithm and making it more difficult
  454. for anyone to bypass or try and hack through it.
  455. So I'm going to put that in place and I've stored this code.
  456. Now because we have that time function there, we have to store the code.
  457. Otherwise when we use it here, we couldn't then use it down here where we need to
  458. use it and then it would get lost.
  459. So in there then I'm going to simply put in my speech marks, my full stops and
  460. add in code. So what that's going to do is if I exist, take
  461. the email address I've given you which exists and its current timestamp hash it as
  462. CRC32 and store it in code. Set an update command to update my users table, change
  463. my password to my code I've just created where the email address is whatever I've
  464. sent you which should exist in my database and then perform that query.
  465. Then I want to go down here I want to set up my SMTP with my username and password
  466. on the right port and I want to set it to send an email from me
  467. to that address which again we've used several times and I'm going to say is html
  468. true it is Parkwood Vale password reset and it's going to say in our message that
  469. your account has requested a password reset and that we want to
  470. give you the code to do so so what I've got is your account has requested
  471. visit HTTP colon for such localhost for slash reset password which
  472. we haven't done yet we will do that in a second and then we're using a get string
  473. now I get string I talked about previously we had get we had post we had put and we
  474. had delete post is generally hidden from the user get is generally visible to the
  475. user both of which we can access using either dollar sign and it's go post a
  476. so we can retrieve that information.
  477. And what we're saying here is go to this webpage,
  478. include, because that's the question mark, the get information for email, which is
  479. our email address,
  480. and the ampersand sign here says, and the token, which is our code we set up here,
  481. which is why it was important to save it because otherwise time would change it
  482. every time we go through it.
  483. Then we're going to go through, we're going to put that in place.
  484. I need to terminate that to stop the error from showing,
  485. user and then catch the error if there is any tell us what the error is but
  486. realistically we shouldn't get any errors anymore now we fixed that PHP fixed that
  487. SMTP outgoing once we've done that we're gonna redirect back to our forgot password
  488. page with our sign-in error saying if you have an account you will receive a reset
  489. email well it's not a sign-in error anymore is it it's a
  490. reset and I'm gonna leave it as error even though technically only one of these is
  491. an error it could be reset message if you wanted to now I do need to pop this back
  492. out and I do need to go into password reset and make sure I push that again yes to
  493. all make sure that's all pushed up brilliant and forgot password here
  494. sign-in error doesn't exist it now is reset error so
  495. forgot password let's put that up as well there we
  496. go now if I go onto this page so I refresh this page a second there's nothing there
  497. I'm gonna go on to here mr. jjones I'm gonna submit it and it's come back if you
  498. have an account you receive a reset email so that's all working perfectly did I get
  499. my reset email yes I did Parkwood Vale library password
  500. reset pocket while via that demo to me and it has your account
  501. reset like I said with this jet string now this is actually
  502. running on a different machine this is a virtual machine this isn't so I need to
  503. copy this a second I'm gonna say copy hyperlink and if I go over to here and paste
  504. that hyperlink then it'll take me and they'll say it cannot find that page I know we
  505. can't find that page I haven't created that page yet that's going to be our next
  506. step so over here let's get that started let's go new file and we called it
  507. reset password dot php
  508. and i can put that there now if i was to put that
  509. and refresh this here it now finds
  510. the page but the page doesn't do anything let's open it up let's have a look let's
  511. put that page in place and let's see what it is we're gonna actually do with it so
  512. PHP to start with session starts at the top
  513. to include our session
  514. we want to include the connection to our database which is
  515. in config forward slash connection
  516. dot PHP let me just double check on these yes it is just simply
  517. conflict there we go so let's have that in place from there the very first thing I
  518. want to do is print for you just so you can all see underscore R and I'm gonna do
  519. under dollar sign underscore get and I want the whole get array
  520. so if I do that and reset password I put that up and I refresh this
  521. page dd line 5 is not happy let's just do print our
  522. get on the whole get array I don't want to specify anywhere and it's telling
  523. me that the email is my email the token is my token from by here but we did an
  524. ambasad here just to show how this is working so add another element I'm going to
  525. say message equals, and I'm going to say
  526. hello. I'm going to do that message hello appears.
  527. Now, this is all in plain text.
  528. Anybody can see that information at the top there.
  529. So it's always important that you don't put anything of high security or high value
  530. in a visible get command. That's why we use
  531. post commands instead.
  532. So we know that works then.
  533. We've got our connection in place.
  534. We've set that up. We're going to first of all check to see if there are any errors.
  535. And the errors are the, sorry, not any errors, any errors.
  536. And password reset. Let's grab this.
  537. We're going to say errors.
  538. Copy that and paste that there.
  539. But it's not going to be post email this time.
  540. it's going to be get email and I'm going to do the same thing with
  541. token so I'm going to say get
  542. token and I'm going to say that the the token field must not be empty
  543. and just like I've done here with my gatekeeper I'm going to check to see if there
  544. are any errors and if there are errors redirecting to the forgot password page
  545. saying error on the password reset
  546. page
  547. please try again now that did show me if I go back
  548. into here a second I've got error on the sign-in page that's not quite right I'm
  549. gonna steal this message I've just written copy it into here
  550. save it and as one last thing password
  551. reset let's make sure I put that perfect so we've gatekeeper there we know now that
  552. we have to have an email and a token to get any further if we haven't got those then
  553. it's not going to do anything I'm going to put in place else to get around that now
  554. so there's my if else command and this is where we're going to be trying
  555. reset their password.
  556. Now we need to show them a sign-in page, we need to show them a page where they can
  557. put in their password so that they can actually go through to this stage and reset
  558. it correctly.
  559. And the way we're gonna do that is we're gonna copy some of the elements that are in
  560. our register page but not the whole thing.
  561. So let me open up my register page, copy all of the code
  562. new file and I'm going to call it new password
  563. .php and I'm going
  564. to highlight it and paste it there.
  565. So the session started. I've got all these details in place.
  566. I don't want first name. I don't want last name.
  567. So I can get rid of those two.
  568. I don't necessarily want email address.
  569. I just want the
  570. password elements here and then I'm gonna have this form host
  571. to my reset password now I know I have
  572. two elements going to the same page a post and again and I'll deal with those in a
  573. second and explain how we're gonna differentiate between them now if it is in
  574. place and it does have its resetted password posted to it then that's when we
  575. need to update our password so let's put that up for a starting point and come back
  576. to here so it's saying does it get information
  577. exists if they get information exists then what we need to do is we want to display
  578. what's in our new password page so I'm gonna head up location
  579. and redirect myself to the new password
  580. page and that's gonna put that in place
  581. that's gonna bring me to this page here but I do need to put in
  582. place
  583. an email equals and I want to put in place what email
  584. they've already given me now without having the email that they've given me
  585. when I go to this new password page I wouldn't be able to go any further than I need
  586. to with this I do need to have my password in on here now my email sorry on here but
  587. it is going to be a type of input that is hidden so type
  588. is hidden the name
  589. is going to be email and the value
  590. is going to be some PHP code
  591. so inside there we can start our PHP tag and end our PHP
  592. tag we can echo what's currently in underscore get
  593. and let's capitalize that get
  594. we can put in place email so we've got that there
  595. we're also going to do the same thing for our token
  596. and that's going to ensure that when we visit that page if the get information is
  597. there it redirect us to this page here with our get information that we need
  598. to progress further so let's go add I'm gonna say token
  599. equals and in here again I'm gonna do
  600. the same thing yeah
  601. token there we go so if I've got to that stage
  602. there and there are no errors because my get information is in place then it should
  603. redirect me to new password which should now exist with these details hidden
  604. as hidden inputs I'm gonna put this as token here
  605. the reason we've got the hidden input for email and for token is that anyone well we
  606. don't want anyone to be able to just hijack and get to that location without the
  607. saying so.
  608. So now if I do this, I should get redirected.
  609. I didn't get redirected.
  610. Let's see. Reset password.
  611. If empty errors, else had a location, new password there.
  612. There we go.
  613. perfect i kept that we need to drop that out so in new password
  614. agree to terms and conditions that can come up as well
  615. now this page here it still has our token information across the top here let me
  616. just refresh that. I didn't put it.
  617. New password page,
  618. put, minimize that and refresh it.
  619. Here we go. It has my get information across the top.
  620. If I actually inspect for a second, you will see that I have a form.
  621. And when I expand it, there are hidden values that have our right hidden information
  622. in place. So that's all working as we want it to.
  623. I'll put in my password there twice and I click submit and it should go forward I do
  624. need to make sure that on new password password repeat phone control password phone
  625. control these two are required and let's do that
  626. again here and save that and let's put that up
  627. and with a refresh I shouldn't be able to submit without them
  628. because it wants it filled in so that's done that's this
  629. new password page done for now we may revisit it to change a few bits and pieces but
  630. the majority of the elements are there we are back on this reset password so we've
  631. got no errors with our get information we want to copy this and
  632. see if we get any errors so do we have any errors trying to get our
  633. post information because our
  634. form will post this information to us along with our
  635. password information so in there if I go back here I called it
  636. password and password repeats so they're there so name is
  637. password and name is password repeat so email is password and password
  638. repeat so when we get down to this section so when we go through the logic we're
  639. going to see do we have the get information yes okay clear that error element if
  640. there's nothing go straight back to that one page once we've cleared that so we have
  641. that get information we can then go on to see do we have any post information.
  642. Once we have our post information check gone through we can say yes we have our post
  643. information and we have got the right details.
  644. If we have any errors so I'm gonna say this same gatekeeper if
  645. empty errors we are going to redirect to this page here so we have changed it up
  646. ever so slightly
  647. and that will allow us to make sure we don't have any errors any information missing
  648. before we go on to try and reset our password with all of that in
  649. place then if i was to submit this here with password so let's do q and
  650. q and i submit it to that the reset password hasn't been
  651. found reset password if I miss type somewhere oh yes I've forgotten
  652. II I got rest password so let's go to new password was it gone
  653. new password I hovered over it and reset password
  654. let's put that up
  655. refresh it just to be sure QQ submit there's an error on the page okay so it's
  656. a look at our logic see what we're doing we come to this page we're gonna see if we
  657. have any gets okay and if we have any errors take it back to there we don't have any
  658. getting that information to the posting that information to it so we need to check
  659. for posting it first then check if we're getting it okay so errors post.
  660. Are we posting it errors from there?
  661. No. Are we getting any information there?
  662. So let's go like that.
  663. So errors is empty.
  664. Do the post information exist or the get information exist?
  665. If there are errors, go back to that page.
  666. Otherwise,
  667. start the array again and check if it's post errors.
  668. If there are post errors, then go to this page.
  669. Okay, should work. and save and let's
  670. put it on that one I want this one
  671. and Q Q submit
  672. Q Q submit
  673. Posting is giving us no errors.
  674. If we post the information, errors is there.
  675. I'm exactly trying get the information and then if errors is
  676. empty then go there
  677. okay so it's done is the post empty yes is the get empty yes go back
  678. there the post empty no come over here we don't need to check again to see if the
  679. post is empty.
  680. If the post is empty, yes.
  681. I think I'm over here and check is.
  682. Well, we should, if post is empty, yes.
  683. Else then.
  684. Okay. So we're saying, is post empty?
  685. Yes. Okay. So If post is empty, then is get empty.
  686. If get is empty, then go to error.
  687. Otherwise, go to new password page.
  688. Q, Q, or two even.
  689. Post.
  690. If empty, error. If not empty.
  691. Let's see what's inside.
  692. Errors.
  693. Print underscore R,
  694. dollar sign, errors.
  695. And let's die so it stops processing anything else.
  696. So I'm on here now. We should have a posted element to go through.
  697. Nothing's changed yet.
  698. New password.
  699. I always put in the wrong file up all the time.
  700. Let's try that again.
  701. There we go. that's what I expected to see and I should be able to go like that and
  702. put the right file up
  703. I do apologize for putting the wrong file up for so long
  704. that's what I expected to see okay so the logic is there I was putting the wrong
  705. file in place
  706. if there's an error on our emails token password or password repeat not being set
  707. then check the get if the get has information in it then show
  708. the re password reset page otherwise show an error
  709. page now a lot of these can be reduced down because we can
  710. use single element ifs but it's not really going to change much it's just
  711. removing those brackets it's not going to be a massive impact on your code.
  712. All of that in place though, we can finally get to the logic where we're actually
  713. going to change that person's password.
  714. Now they have sent us their password, they've also sent us their email without
  715. knowing it, so we can use the update command like we did in our password reset
  716. function.
  717. And it is just this one here.
  718. Now, password reset down by here.
  719. What I'm going to do is I'm going to say update users set password equal to, this
  720. time around, get password
  721. where email is equal to email and then run that query.
  722. Really simple.
  723. from my login function now that's my login page is my sign-in function
  724. that I want to select the details and redirect
  725. them to their account page so reset here then I've updated their password I'm going
  726. to select email for name and surname and is admin from users where email is equal to
  727. email and password is equal to password when it's been hashed and then
  728. put that in place I got a bit of an error here because I had an if I just need to
  729. put that there now that has given me a vital reminder that our password should be
  730. hashed and it's not by here so set password to equal get password would not work
  731. I have to do set passwords equal to and copy that it's not the
  732. get password it is the post
  733. password there where that's all set up and that's all in place so let's go through
  734. post post post post perfect get get perfect there so update
  735. users set password equal to whatever they set in a password where email
  736. is equal to that and I want to put in one last security element I think I say
  737. and password is equal to
  738. and
  739. what we're gonna be looking for is our dollar
  740. sign underscore host and this is going to be token
  741. so what happens is it says does this username
  742. and tokened password match? If so, set the password to what the
  743. user said. Then go through and redirect them to that element there.
  744. If that doesn't work, just like we did with our login beforehand, we need to
  745. redirect them. So I'm going to say else
  746. and I'm going to say that there is an error on the password page.
  747. Please try again and redirect them back to that section there so all in all i
  748. have the ability now to reset a password if i come here and i refresh this
  749. page ever so slightly we have our token let me just get hidey open we can have a
  750. look at what's going on in the database while we do this HeidiSQL database
  751. thank you open
  752. and let's go to users data you can see not the password token
  753. is 38C182B2, what it is up here.
  754. I'm going to put in password123,
  755. password123 again, and submit.
  756. Now that's taking me through to reset password.
  757. And if I refresh this, nothing's changed.
  758. Chances are, I haven't put this page up properly.
  759. It's one of my most common errors.
  760. And let's refresh that.
  761. I've gone to my account details it's found the information about my account
  762. it does have an error in place but we won't worry about that too much right now and
  763. if I refresh this it's changed my password to password123 so that password
  764. reset functionality is all fully working and just to show you again if I go into
  765. forgot password I put in my email address and submit it it comes
  766. reset email so let's see here's my reset email
  767. again it's a completely different code my token here that's because it's related to
  768. the users time as well I'm gonna paste that here
  769. it's gonna bring me to my password reset page
  770. oh it's not it should have done.
  771. Refetch, there we go.
  772. So that is there.
  773. Reset password.
  774. Okay, so there is definitely still some gremlins in this logic here.
  775. Get email and get tokens.
  776. Not if they're empty. Okay.
  777. i'm going to print here underscore r and errors
  778. to see what the gremlins are and again i'm going to use the die command
  779. just to prevent it from processing any further php commands on my reset password
  780. email
  781. field must not be empty
  782. all right so there's my ah okay that makes sense i get to here
  783. and i haven't reset
  784. errors to an empty array because i haven't reset errors to an empty array
  785. it's still finding the previous errors and redirecting me there but now by resetting
  786. those errors to an empty array if I put that and refresh this page I should
  787. get no errors if I remove my print and my die commands and I put that
  788. and refresh this it shows me that I
  789. put in password one two three
  790. password one two three submit I'm to my account if I come here
  791. and use that password
  792. 123 submit blogs me in so we have all of that functionality running right the way
  793. through we can request a new password via email it will send the email we can
  794. authenticate that we've received that email and reset our passwords i know it was a
  795. hell of a lot in today's session you can see why i want to do this session
  796. separately no i don't want to save any queries
  797. going through setting up the SMTP is an important step and you can see the emails
  798. from SMTP that have been sent you will have to set it up in some fashion it is
  799. possible to I'd say it's possible that using Outlook
  800. or Hotmail might be an easier solution because I don't think they have the same
  801. requirements in place for the app specific passwords but I wanted to go through one
  802. of the more difficult ones with you so that you have the full steps there, what
  803. you choose to do with your learners is completely up to you.
  804. This is a difficult session. This is why it's had a session all dedicated completely
  805. to itself. If there are any issues, any complications, any confusion, anyone not
  806. getting this code working, please do not hesitate to reach out and contact me, and I
  807. will do my best to try and triage what's going on and perhaps redo a bit more of a
  808. video to go into more depth about something if it's needed.