Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:02,070 --> 00:00:03,350
So let's now get started
2
00:00:03,350 --> 00:00:05,120
with adding our own logic,
3
00:00:05,120 --> 00:00:08,700
because as I said NextAuth won't do everything for us here.
4
00:00:08,700 --> 00:00:12,430
When we roll with our own authentication system
5
00:00:12,430 --> 00:00:13,940
with our own user accounts
6
00:00:13,940 --> 00:00:18,000
and thereafter before we use NextAuth for anything,
7
00:00:18,000 --> 00:00:19,170
we will first of all,
8
00:00:19,170 --> 00:00:22,240
have to add the logic to create users
9
00:00:22,240 --> 00:00:23,930
because NextAuth can then
10
00:00:23,930 --> 00:00:26,660
help us with authenticating those users
11
00:00:26,660 --> 00:00:29,150
and with getting the token for those users,
12
00:00:29,150 --> 00:00:31,300
but to create the users themselves,
13
00:00:31,300 --> 00:00:33,720
we need to bring our own logic.
14
00:00:33,720 --> 00:00:36,310
Hence I'll bring up my dev server again,
15
00:00:36,310 --> 00:00:38,850
and I want to add an API route,
16
00:00:38,850 --> 00:00:41,110
which gets input,
17
00:00:41,110 --> 00:00:44,800
which gets a request with an email and a password,
18
00:00:44,800 --> 00:00:47,490
which in the end should be sent from the log in page,
19
00:00:47,490 --> 00:00:50,160
if we are creating a new account
20
00:00:50,160 --> 00:00:53,890
and then that data should be used to store that user,
21
00:00:53,890 --> 00:00:57,250
and I will use MongoDB again as a database
22
00:00:57,250 --> 00:00:59,110
for storing the user data,
23
00:00:59,110 --> 00:01:02,600
but you can go with any database you want.
24
00:01:02,600 --> 00:01:04,819
It doesn't have to be MongoDB,
25
00:01:04,819 --> 00:01:06,300
but MongoDB
26
00:01:06,300 --> 00:01:08,260
especially when using MongoDB Atlas
27
00:01:08,260 --> 00:01:09,970
is just great to use,
28
00:01:09,970 --> 00:01:11,350
free to get started,
29
00:01:11,350 --> 00:01:13,110
easy to use with Javascript
30
00:01:13,110 --> 00:01:15,280
and already hosted for us,
31
00:01:15,280 --> 00:01:16,380
so that's great.
32
00:01:16,380 --> 00:01:18,400
Hence we'll need to add an API route
33
00:01:18,400 --> 00:01:21,900
and therefore this API folder in the pages folder,
34
00:01:21,900 --> 00:01:26,330
and in that API folder, I'll then add an auth subfolder,
35
00:01:26,330 --> 00:01:28,283
and in that auth subfolder,
36
00:01:29,285 --> 00:01:30,980
a sign up JS file.
37
00:01:30,980 --> 00:01:32,900
Now the file name is up to you,
38
00:01:32,900 --> 00:01:36,870
and in there I'll then define my handler function
39
00:01:36,870 --> 00:01:40,330
which will be responsible for creating a new user,
40
00:01:40,330 --> 00:01:41,170
and we should of course,
41
00:01:41,170 --> 00:01:43,713
as always export that function thereafter.
42
00:01:44,930 --> 00:01:47,440
Now in here, we want to connect
43
00:01:47,440 --> 00:01:51,110
to the database and store the incoming user data.
44
00:01:51,110 --> 00:01:54,320
Hence I will actually quit the dev server one more time
45
00:01:54,320 --> 00:01:58,130
and then install the MongoDB package again
46
00:01:58,130 --> 00:02:01,050
as we also did before in the course already
47
00:02:01,050 --> 00:02:03,420
and then restart the dev server
48
00:02:03,420 --> 00:02:05,490
because we'll need that MongoDB package
49
00:02:05,490 --> 00:02:08,440
to successfully connect to that database
50
00:02:08,440 --> 00:02:10,423
and talk to that database.
51
00:02:11,270 --> 00:02:14,900
We will actually also talk to that database
52
00:02:14,900 --> 00:02:18,630
from multiple functions here
53
00:02:18,630 --> 00:02:20,770
from multiple API routes later
54
00:02:20,770 --> 00:02:22,810
and therefore to share some logic,
55
00:02:22,810 --> 00:02:27,760
I'll add a new folder on my route level of the project,
56
00:02:27,760 --> 00:02:29,470
a lib folder,
57
00:02:29,470 --> 00:02:32,430
we could also name it, helpers, whatever you want,
58
00:02:32,430 --> 00:02:37,210
and in there I'll add my DB JS file,
59
00:02:37,210 --> 00:02:38,890
file name of course is up to you
60
00:02:38,890 --> 00:02:41,210
and it's that file, which should help me
61
00:02:41,210 --> 00:02:44,383
with establishing a connection and so on.
62
00:02:45,230 --> 00:02:47,720
So here in this DB JS file,
63
00:02:47,720 --> 00:02:50,220
I'll import from MongoDB,
64
00:02:50,220 --> 00:02:51,990
and as before in the course,
65
00:02:51,990 --> 00:02:55,040
I'll import Mongo client
66
00:02:55,040 --> 00:02:56,730
because that's the thing
67
00:02:56,730 --> 00:02:58,983
that helps us establish a connection,
68
00:03:00,340 --> 00:03:01,850
and then I'll add a function,
69
00:03:01,850 --> 00:03:06,850
connecTtoDatabase, could be the function name
70
00:03:07,030 --> 00:03:09,450
and in there we'll do what the name implies.
71
00:03:09,450 --> 00:03:12,880
We'll use Mongo client to call the connect method,
72
00:03:12,880 --> 00:03:15,660
and then here pass our connection string
73
00:03:15,660 --> 00:03:18,350
with which we connect to a database.
74
00:03:18,350 --> 00:03:21,660
Now for MongoDB, we can get that string from
75
00:03:21,660 --> 00:03:24,830
MongoDB Atlas with a created cluster,
76
00:03:24,830 --> 00:03:26,150
and therefore you should make sure
77
00:03:26,150 --> 00:03:27,950
that you have that cluster.
78
00:03:27,950 --> 00:03:30,710
We did create that early in the course already,
79
00:03:30,710 --> 00:03:33,890
so make sure that you don't skip those previous parts
80
00:03:33,890 --> 00:03:36,230
where we talk to MongoDB already,
81
00:03:36,230 --> 00:03:38,470
and once you've got a cluster created,
82
00:03:38,470 --> 00:03:40,800
you can click on connect on your cluster,
83
00:03:40,800 --> 00:03:42,340
connect your application,
84
00:03:42,340 --> 00:03:44,460
and then it's this connection string
85
00:03:44,460 --> 00:03:48,220
which we need and which we are interested in.
86
00:03:48,220 --> 00:03:50,310
So I'll use that connection string,
87
00:03:50,310 --> 00:03:53,020
and here we now need to replace
88
00:03:53,020 --> 00:03:56,830
some pieces of data like the username, password
89
00:03:56,830 --> 00:04:00,050
and the database here.
90
00:04:00,050 --> 00:04:02,090
Now for username and password,
91
00:04:02,090 --> 00:04:04,110
I will go to database access
92
00:04:04,110 --> 00:04:06,590
and make sure that I have a valid password
93
00:04:06,590 --> 00:04:08,693
for this user here,
94
00:04:09,620 --> 00:04:11,790
create a new password and update it,
95
00:04:11,790 --> 00:04:13,820
and then use my username.
96
00:04:13,820 --> 00:04:17,350
You need at least one user with read and write access
97
00:04:17,350 --> 00:04:20,220
created in MongoDB Atlas
98
00:04:20,220 --> 00:04:22,233
and then add the password here,
99
00:04:24,260 --> 00:04:26,060
and then for the database name,
100
00:04:26,060 --> 00:04:28,380
I'll name this auth-demo,
101
00:04:28,380 --> 00:04:30,563
but that database name is up to you.
102
00:04:31,470 --> 00:04:33,340
That's now the connection string.
103
00:04:33,340 --> 00:04:36,940
Now connect returns a promise and to use async await,
104
00:04:36,940 --> 00:04:39,250
I'll add async in front of the function
105
00:04:39,250 --> 00:04:42,880
and then await this a connection result here
106
00:04:42,880 --> 00:04:45,570
or to be precise to connect the client
107
00:04:45,570 --> 00:04:47,633
which we get back as a response.
108
00:04:48,750 --> 00:04:51,240
Now this could be failing but for the moment,
109
00:04:51,240 --> 00:04:52,440
let's ignore that,
110
00:04:52,440 --> 00:04:56,270
and let's then just return that client here maybe,
111
00:04:56,270 --> 00:04:58,520
so that when someone calls connectToDatabase,
112
00:04:59,600 --> 00:05:02,263
that someone gets this client.
113
00:05:03,570 --> 00:05:07,240
Now that function should be usable from outside this file.
114
00:05:07,240 --> 00:05:09,030
So we'll export it,
115
00:05:09,030 --> 00:05:12,570
and now back in the sign up JS API route here,
116
00:05:12,570 --> 00:05:15,830
I first of all want to call connectToDatabase
117
00:05:15,830 --> 00:05:20,073
and hence import this from that lib folder and the DB file.
118
00:05:20,920 --> 00:05:23,360
Now I'll also turn this into an async function
119
00:05:23,360 --> 00:05:25,200
to use await here,
120
00:05:25,200 --> 00:05:28,390
and then here we get that connected client
121
00:05:28,390 --> 00:05:31,030
and we can then get access to the complete database
122
00:05:31,030 --> 00:05:35,360
by calling client.db() like this,
123
00:05:35,360 --> 00:05:37,490
and now that we've got access to the database,
124
00:05:37,490 --> 00:05:40,020
we want to create a new user
125
00:05:40,020 --> 00:05:43,790
and store it in some collection of that database,
126
00:05:43,790 --> 00:05:46,800
because as you learned before in this course already,
127
00:05:46,800 --> 00:05:49,250
MongoDB works with collections,
128
00:05:49,250 --> 00:05:50,860
collections of documents,
129
00:05:50,860 --> 00:05:53,970
where a single user would be a document
130
00:05:53,970 --> 00:05:58,530
and all the users would be stored together in a collection.
131
00:05:58,530 --> 00:05:59,870
We get access to a collection
132
00:05:59,870 --> 00:06:03,050
by calling the collection method on DB
133
00:06:03,050 --> 00:06:05,250
and we can use any collection we want.
134
00:06:05,250 --> 00:06:09,420
If it's doesn't exist yet, it will be created on the fly.
135
00:06:09,420 --> 00:06:13,440
So here we could maybe work with a users collection.
136
00:06:13,440 --> 00:06:15,520
Now to get the submitted user data
137
00:06:15,520 --> 00:06:17,160
we should accept the request
138
00:06:17,160 --> 00:06:21,460
and response objects here in our API route function.
139
00:06:21,460 --> 00:06:25,580
You'll learn that API route functions give us access
140
00:06:25,580 --> 00:06:27,160
to the incoming request
141
00:06:27,160 --> 00:06:29,360
and then all the tutors' response object
142
00:06:29,360 --> 00:06:31,430
to send back a response,
143
00:06:31,430 --> 00:06:34,190
and then we want to extract the incoming data,
144
00:06:34,190 --> 00:06:37,320
and actually we maybe want to do that first
145
00:06:37,320 --> 00:06:39,160
so that we only proceed
146
00:06:39,160 --> 00:06:42,193
as soon as we know that we have valid data.
147
00:06:43,050 --> 00:06:46,360
So here, we then basically get our data
148
00:06:46,360 --> 00:06:49,020
by accessing request body,
149
00:06:49,020 --> 00:06:51,110
and then from there we get our,
150
00:06:51,110 --> 00:06:53,700
let's say email and password,
151
00:06:53,700 --> 00:06:56,120
and these key names are up to you.
152
00:06:56,120 --> 00:06:59,180
I will extract them from the incoming request body.
153
00:06:59,180 --> 00:07:01,380
We will just have to make sure
154
00:07:01,380 --> 00:07:04,210
that later when we submit this form,
155
00:07:04,210 --> 00:07:07,411
this auth form that we actually do add
156
00:07:07,411 --> 00:07:10,520
email and password to the request
157
00:07:10,520 --> 00:07:12,610
which we sent to this API route
158
00:07:12,610 --> 00:07:14,623
when we want to create a user.
159
00:07:15,890 --> 00:07:18,330
So thereafter now we got that,
160
00:07:18,330 --> 00:07:20,490
and now we got email and password,
161
00:07:20,490 --> 00:07:23,230
we definitely also want to validate it.
162
00:07:23,230 --> 00:07:27,290
We want to check that we don't store invalid data.
163
00:07:27,290 --> 00:07:29,410
So if we don't have an email
164
00:07:29,410 --> 00:07:34,410
or let's say if not email includes an at symbol
165
00:07:34,740 --> 00:07:37,950
or if we don't have a password
166
00:07:37,950 --> 00:07:42,260
or if password trimmed for white space
167
00:07:42,260 --> 00:07:46,410
has a length that is let's say smaller than seven,
168
00:07:46,410 --> 00:07:49,220
so that we require at least seven characters
169
00:07:49,220 --> 00:07:50,940
for security reasons,
170
00:07:50,940 --> 00:07:53,750
if any of these conditions is met,
171
00:07:53,750 --> 00:07:56,720
so if we have invalid data,
172
00:07:56,720 --> 00:07:59,050
then I want to return to not continue
173
00:07:59,050 --> 00:08:00,790
with function execution
174
00:08:00,790 --> 00:08:03,210
and I'll send back a response
175
00:08:03,210 --> 00:08:06,220
with a 422 status code
176
00:08:06,220 --> 00:08:08,290
and some extra information
177
00:08:08,290 --> 00:08:12,660
like a message where I say invalid input,
178
00:08:12,660 --> 00:08:17,660
password should also be at least seven characters long,
179
00:08:19,410 --> 00:08:20,563
something like this.
180
00:08:22,390 --> 00:08:24,260
That's the response we sent back
181
00:08:24,260 --> 00:08:26,393
if we got invalid input.
182
00:08:27,230 --> 00:08:29,600
If we make it past this if check, though,
183
00:08:29,600 --> 00:08:31,680
we know that we have valid input
184
00:08:31,680 --> 00:08:36,210
and then we want to store our user data in the database.
185
00:08:36,210 --> 00:08:37,722
So in that users collection,
186
00:08:38,750 --> 00:08:41,659
hence here we want to insert a new document.
187
00:08:41,659 --> 00:08:43,460
We can do this with insert one,
188
00:08:43,460 --> 00:08:45,610
as we saw before in the course,
189
00:08:45,610 --> 00:08:48,900
and we can create that document on the fly here
190
00:08:48,900 --> 00:08:51,780
and simply add the email field
191
00:08:51,780 --> 00:08:56,120
which is that extracted email we got here,
192
00:08:56,120 --> 00:08:57,973
and then the password.
193
00:08:58,890 --> 00:09:01,260
However, regarding the password,
194
00:09:01,260 --> 00:09:06,210
there is something we have to keep in mind and take care of.
195
00:09:06,210 --> 00:09:08,830
We should not store the plain password
196
00:09:08,830 --> 00:09:11,120
like this in the database,
197
00:09:11,120 --> 00:09:14,760
because if our database ever gets compromised
198
00:09:14,760 --> 00:09:18,440
by some employee or a third party intruder,
199
00:09:18,440 --> 00:09:21,110
then all our user credentials
200
00:09:21,110 --> 00:09:24,270
would be usable just like this.
201
00:09:24,270 --> 00:09:26,790
Hence for security reasons,
202
00:09:26,790 --> 00:09:30,440
it is a best practice and strongly recommended,
203
00:09:30,440 --> 00:09:34,460
that you don't store plain passwords in the database
204
00:09:34,460 --> 00:09:36,750
but that you instead encrypt them
205
00:09:36,750 --> 00:09:39,920
such that they can't be decrypted,
206
00:09:39,920 --> 00:09:43,030
and we will still be able to verify them later, no worries,
207
00:09:43,030 --> 00:09:45,900
but we want to make sure that we store passwords
208
00:09:45,900 --> 00:09:47,440
in encrypted form
209
00:09:48,390 --> 00:09:50,160
and to encrypt passwords,
210
00:09:50,160 --> 00:09:52,860
we can install another third party package
211
00:09:52,860 --> 00:09:57,720
with npm install and that's bcryptjs, like this.
212
00:09:58,770 --> 00:10:02,770
That's a package which helps us encrypt passwords
213
00:10:02,770 --> 00:10:04,990
or encrypt any kind of data of course,
214
00:10:04,990 --> 00:10:07,160
but we'll use it for a password here,
215
00:10:07,160 --> 00:10:09,420
and hence, I'll start my dev server again,
216
00:10:09,420 --> 00:10:11,950
and now I want to encrypt my password
217
00:10:11,950 --> 00:10:13,590
and for this in the lib folder,
218
00:10:13,590 --> 00:10:16,380
I'll add another folder auth.js,
219
00:10:16,380 --> 00:10:19,430
which will hold those authentication
220
00:10:19,430 --> 00:10:22,640
related utility methods,
221
00:10:22,640 --> 00:10:26,460
and here I want to import from bcryptjs
222
00:10:27,600 --> 00:10:30,320
from that package we just installed,
223
00:10:30,320 --> 00:10:34,770
and from there, I want to import the hash function.
224
00:10:34,770 --> 00:10:39,770
Then I want to export an async function called hashPassword
225
00:10:42,560 --> 00:10:47,560
and take the original plain text password as an input,
226
00:10:47,750 --> 00:10:48,860
and then in there,
227
00:10:48,860 --> 00:10:52,090
call hash on that password,
228
00:10:52,090 --> 00:10:54,270
and the second argument then should be a number
229
00:10:54,270 --> 00:10:55,890
of salting rounds,
230
00:10:55,890 --> 00:10:59,530
which in the end will influence how strong that password is,
231
00:10:59,530 --> 00:11:04,180
and here a value of 12 is considered to be safe.
232
00:11:04,180 --> 00:11:05,210
The higher the number,
233
00:11:05,210 --> 00:11:07,080
the longer this function will take,
234
00:11:07,080 --> 00:11:09,740
the lower the number, the more insecure it is,
235
00:11:09,740 --> 00:11:13,050
so 12 should be an okay value
236
00:11:13,050 --> 00:11:15,960
and hash will then also return a promise
237
00:11:15,960 --> 00:11:18,920
which eventually gets gives us that encrypted password.
238
00:11:18,920 --> 00:11:23,550
So we can await this to have our hashed password here
239
00:11:23,550 --> 00:11:24,730
in the end,
240
00:11:24,730 --> 00:11:27,100
and then it's this hashed password
241
00:11:27,100 --> 00:11:29,730
which I return just like this.
242
00:11:29,730 --> 00:11:32,590
Now back in signup.js, we therefor now
243
00:11:32,590 --> 00:11:35,180
want to create such a hashed password
244
00:11:35,180 --> 00:11:36,920
and store data in our collection
245
00:11:36,920 --> 00:11:39,060
instead of the plain password.
246
00:11:39,060 --> 00:11:43,700
So here I get the hashed password
247
00:11:43,700 --> 00:11:48,140
by calling hashPassword and importing that function
248
00:11:48,140 --> 00:11:51,433
from the lib folder and the auth file there,
249
00:11:52,400 --> 00:11:54,010
and then to hashPassword,
250
00:11:54,010 --> 00:11:56,650
we pass our plain text password
251
00:11:57,810 --> 00:11:59,720
and then it's this hashed password,
252
00:11:59,720 --> 00:12:01,340
which we store in the document.
253
00:12:01,340 --> 00:12:02,963
So in the collection overall.
254
00:12:04,340 --> 00:12:06,530
Now insert one always returns a promise,
255
00:12:06,530 --> 00:12:08,120
so we can await this
256
00:12:08,120 --> 00:12:11,240
and this will return the result of this operation,
257
00:12:11,240 --> 00:12:13,250
which then for example gives us access
258
00:12:13,250 --> 00:12:16,690
to the automatically generated user ID.
259
00:12:16,690 --> 00:12:19,910
Now with that, we're storing a user in the database
260
00:12:19,910 --> 00:12:21,780
and now I want to send back
261
00:12:21,780 --> 00:12:24,980
a response offer, a success response
262
00:12:24,980 --> 00:12:29,980
where we say something like created user.
263
00:12:30,030 --> 00:12:32,860
Now I'll not implement error handling here,
264
00:12:32,860 --> 00:12:35,940
since I really want to focus on the core auth parts,
265
00:12:35,940 --> 00:12:39,510
and we saw error handling with MongoDB and so on,
266
00:12:39,510 --> 00:12:41,330
in action before already,
267
00:12:41,330 --> 00:12:43,610
and hence, I'll keep this lean and focused
268
00:12:43,610 --> 00:12:48,610
on the parts that are related to user creation in this case,
269
00:12:48,800 --> 00:12:51,810
and then for now we should be able to test this.
270
00:12:51,810 --> 00:12:53,020
In the next lecture,
271
00:12:53,020 --> 00:12:55,430
let's make sure that we send the request
272
00:12:55,430 --> 00:12:57,673
to this signup API route.
20758
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.