MEAN Stack 结合 Angular 4、Auth0 认证及 JWT 授权 - 第一部分





5.00/5 (1投票)
MEAN Stack,开发环境搭建,Expressjs API 开发与测试
文章系列
- 第一部分:MEAN Stack,开发环境搭建,Expressjs API 开发与测试
- 第二部分:Angular 4 客户端开发
- 第三部分:使用 Auth0 和 JWT 进行认证与授权
引言
在本系列短文中,我将通过开发我们最喜欢的 用户管理 应用,一步步讲解使用 MEAN Stack(结合 Angular 4)的应用开发。之后,我们将使用 Auth0 添加用户认证,并通过 JWT (JSON Web Token) 授权我们的 RESTful API 请求。我们将在 Visual Studio Code 编辑器中开发我们的应用。
背景
虽然这是一个独立的系列文章,但最好您先阅读 用户管理 这篇文章。我们将使用与用户管理几乎相同的 Angular 2/4 代码,只是通过 Angular CLI 命令创建组件、服务、模块等。
MEAN 代表 Mongo、Expressjs、Angular 和 Node.js。对这些技术有基本了解会很有帮助,但并非必需。我将在开发过程中简要解释每种技术。
我们将开发什么以及如何开发?
我们将从 这里 下载用户管理(添加
/更新
/删除
/加载
)应用。我们将下载 node.js、Visual Studio Code,通过 node.js NPM 安装 Angular CLI,在 Auth0 上创建账户以用于认证,并在 mLab 上创建 MongoDB,我们将在这里存储用户信息,而不是使用 SQL 数据库。
以下是我们即将执行的步骤总结
- 安装所有必需软件并创建
Auth0
和mLab
账户。 - 创建一个新项目并在 Visual Studio Code 中打开项目。
- 创建 Node.js 服务器,连接到
mLab
并通过 Expressjs 暴露用户 CRUD RESTful API。 - 通过 Angular CLI 命令根据 此 用户管理应用创建所需的组件、服务和路由。
- 更新 Angular 客户端应用以调用 Expressjs 暴露的 RESTful API。
- 验证应用功能。
- 添加登录功能,实现
AuthGuard
以保护用户管理页面路由。 - 在 Angular 客户端和 Expressjs 服务器端实现 JWT,以保护数据通信。简单来说,Angular 客户端会在
GET
、POST
、PUT
和DELETE
请求中发送 JSON Web Token(一种通过哈希算法哈希的字符串),服务器端会由 Expressjs 进行验证,以确保未经授权的用户无法访问。 - 最后,我们将学习 Karma、Jasmine 测试,以及 AOT 等构建。 (可选)
仍然感兴趣?
设置开发环境
- 下载 Visual Studio Code 并安装,如果您还没有的话。
- 下载 Node.js 并安装,如果您没有最新版本的话。安装完成后,打开命令提示符并运行
node -v
命令以验证安装成功并获取 node 版本。 - 打开命令提示符并使用
npm install -g @angular/cli
命令安装 Angular CLI。安装完成后,运行ng -v
命令以检查安装成功并获取 Angular CLI 版本。 - 访问 https://auth0.com/ 网站,点击右角的 **SIGN UP** 按钮。输入
Email
和Password
,或使用 Github、Google 或 Microsoft 账户注册。随您选择。注册后,系统会要求您输入ACCOUNT NAME
,输入任何唯一的名称,然后点击底部的 **Next** 按钮。在下一页输入具有描述性的信息,然后点击 **Create Account** 按钮。您将收到一封验证邮件到您注册时使用的电子邮件地址。点击邮件中的 **Verify Your Account** 按钮或链接,使用您的凭证登录,您将被重定向到一个页面,显示验证成功和 21 天试用期信息。目前就这些,先放到这里,我们稍后再回来。 - 访问 https://mlab.com/ 网站,点击右角的 **SIGN UP** 按钮。输入新账户信息,然后点击 **Create Account** 按钮。您将收到一封验证邮件到您注册时使用的电子邮件地址。点击邮件中的 **Verify Your Account** 链接,使用您的凭证登录,您将被重定向到一个验证成功的页面。先放到这里,我们稍后再回来创建
collection
和documents
。 - 环境搭建就到这里,我们将在应用中通过 npm (Node Package Manager) 添加 Angular 和 node.js 所需的客户端包。
开始吧
- 创建项目文件夹 mean-example,并在其中创建两个文件夹:server 和 client。在 server 文件夹中,我们将创建一个 node.js 应用,连接到
mLab
网站(用于MongoDB
),通过Expressjs
创建用户 CRUD RESTful API。在 client 文件夹中,我们将存放 Angular 代码,该代码将调用 Expressjs API 并在浏览器中渲染视图。 - 接下来,打开 Visual Studio Code,选择 **File -> Open Folder...**。选择新创建的 mean-example 文件夹,然后点击 **Select Folder** 按钮。
- 您将在 **EXPLORER** 面板中看到两个空文件夹:client 和 server。(如果 Explorer 不可见,请选择顶部菜单 **View -> Explorer**)。
- 首先,让我们创建服务器端应用。如前所述,我们将使用 node.js 和 Expressjs 开发服务器端应用,但在开始开发之前,让我们先了解一下 node.js 和 Expressjs。
- Node.js:您会在网上找到很多花哨的定义,但简单来说,它是一个用 JavaScript 编写的应用和网站的服务器端框架,速度快且非阻塞。如何做到的?仅为理解,当它执行任何任务时,它不会停在那里等待完成,而是会向其注册一个回调函数,然后继续执行下一任务。当前任务完成后,它会调用回调函数通知其完成,依此类推。这使得 node.js 成为事件驱动的,就像事件将在一次(当 Node 准备好调用回调时)触发,回调充当事件处理程序。现在 node.js 本身的功能很薄弱,因此我们有很多库/模块可以导入到 node.js 应用中以执行所需的功能。其中之一就是 Expressjs。
- Expressjs:一个用于 Web 应用、RESTful API 的 node.js 框架,您还可以在其中定义 路由。Expressjs 灵活支持任何 模板 框架(HTML 或视图文件),例如 Jade、Pug 或 EJS。由于我们使用 Angular 4 作为客户端,并且不在服务器端创建任何模板/视图,所以目前不用担心任何模板框架。我们将仅使用 EJS 来渲染我们的 HTML。我们的 Expressjs 将指向 dist 文件夹,该文件夹将在我们使用 Angular CLI
build
命令构建 Angular4 客户端后生成(稍后我们将简要介绍)。
- 虽然您可以使用 Express Application Generator CLI 来生成 Express 服务器、pug 视图、路由、文件夹等。但我将手动创建所需的文件,因为我只需要少量文件。您可以自行尝试 Express CLI。
- 右键单击 server 文件夹,选择 **New File**。输入文件名 app.js。这将是我们的 node.js 服务器文件。
- 接下来,我们将通过
npm
获取Expressjs
模块。我将单独保留服务器和客户端的 package.json 文件。右键单击 **EXPLORER** 面板中的 server 文件夹,选择 **Open in Command Prompt**。首先,我们将在 server 文件夹中创建 package.json 文件。在命令提示符中输入命令npm init
并按 **Enter**,它会询问一些信息,例如应用程序名称、作者、描述等。在此处添加或一直按 Enter,最后按yes
。您将在 server 文件夹中找到已创建的 package.json 及其基本结构,很好。 - 输入以下命令安装 Expressjs:
npm install express --save
。检查 package.json 文件,在 **dependencies** 部分,您会找到 "express": "^4.15.4"(或任何更新版本)。 - 接下来,在命令提示符中运行
npm install body-parser --save
&npm install ejs --save
命令。我们已经讨论过 EJS,它是您可以在 Expressjs 中使用的 JavaScript 模板,用于渲染视图。 - 编辑 app.js 文件,暂时添加所需的外部模块
express
、path
和bodyparser
。//Expressjs module, require is node.js syntax to import the module. var express = require('express'); //For file path, we will use it to point the Angular dist folder. var path = require('path'); //body-parser extracts the entire body portion of an incoming //request stream and exposes it on req.body. var bodyParser = require('body-parser');
- 接下来,添加以下代码
var port = 3000; var app = express(); app.use('/', function(req, res){ res.send("I am up & running at port: "+ port); }); app.listen(port, function(){ console.log('Server started on port '+port); });
- 上面的代码非常自 explanatory,我们指定了应用程序端口,创建了 expressjs 实例。在下一条语句中,我们指定如果有一个未指定路由的 localhost URL,则只向浏览器发送文本 "
I am up & running at port: 3000
"。Express 的use
方法允许我们的应用程序使用外部路由作为应用程序的一部分。app.listen
将打开/使用指定的端口 (3000) 用于 localhost。确保此端口未被任何其他进程使用。您可以指定任何可用端口。 - 右键单击 server 文件夹,选择 **Open in Command Prompt** 选项。输入命令
node app
并按 Enter。您会看到Server started on port 3000
消息。现在打开任何浏览器,例如 Chrome 或 Firefox,然后浏览 URL https://:3000。您会在浏览器中看到I am up & running at port: 3000
消息。很酷,这是快速测试服务器设置的方法。 -
下一步是在 MongoDB 中设置
User
数据库,并在 Expressjs 中暴露 RESTful CRUD API。打开 https://mlab.com 网站,使用上一步创建的凭证登录。登录后,您将进入以下页面: -
在
MongoDB Deployment section
的顶部,点击 **Create New** 按钮。在下一个屏幕中,选择 **Plan Type SANDOX**。点击 **SANDOX** 后,底部会出现 **Continue** 按钮,点击它。 -
由于这个免费数据库将在 AWS 上创建,下一个屏幕会要求您选择 AWS 区域,选择您最近/所需的区域。我在弗吉尼亚州,所以我将选择 US East (Virginia),选择 **Region** 后,点击底部的 **Continue** 按钮。
-
输入数据库名称
userdb001
,然后点击底部的 **Continue** 按钮。 -
点击底部的 **Submit Order** 按钮。
-
片刻之后,您将进入主页,您的数据库已可用并准备就绪。
- 在上图中,点击以
ds149353...
开头的新创建的行,您将进入以下屏幕。此页面包含重要信息,例如 MongoDB URI,我们将通过它从 node.js 连接到 MongoDB。其他信息是关于数据库Collections
、Users
、Backups
等。目前我们将使用 **Collections** 和 **Users** 选项卡。- Collections:您可以在线获取 MongoDB Collections 的定义,但由于我不是定义的忠实粉丝。仅为理解,请将
Collection
视为关系数据库的表
。就像关系数据库表
可以有多个行一样,在 MongoDB 中,一个Collection
可以有多个documents
,当然,您可以根据需要创建任意数量的Collections
。 - Document:
Document
只是一个 JSON 数据文件(键、值)对。我们将在后续步骤中看到document
的确切外观。
- Collections:您可以在线获取 MongoDB Collections 的定义,但由于我不是定义的忠实粉丝。仅为理解,请将
-
点击 **Add Collection** 按钮,在弹出模态框中,输入 **Collection name** 为
UserInfo
,然后点击 **Create** 按钮。 -
太棒了,让我们创建一个示例文档,点击
UserInfo
collection(红色区域)。您将进入以下屏幕。点击 **Add document** 按钮。 -
您将进入以下编辑器,现在根据第二个截图在 **Create Document** 编辑器中添加 JSON 数据,然后点击 **Create and go back**。
-
太好了!您会看到新的 JSON
document
已创建,并且有一个自动分配的唯一_id
,这是一个很棒的功能。 -
接下来,让我们创建数据库
User
,点击上一步截图顶部的userdb001
。点击 **Users** 选项卡,然后点击 **Add database user**,输入用户名admin
和密码123456
。(或者您喜欢的任何内容,但请记住它)。点击 **Create** 按钮。 - 这就是我们在
mLab
网站上需要做的全部,记下 **To connect using a driver via the standard MongoDB URI** 的值。对您来说,这个值会不同。我们需要它来从 node.js 连接 MongoDB。 - 现在让我们回到 node.js,我们需要
mongojs
包来从mLab
网站连接到 MongoDB。重复相同的步骤,如果您的命令提示符尚未打开,右键单击 server 文件夹并选择 **Open in Command Prompt**,输入命令npm install mongojs --save
。 - 编辑 server 文件夹中的 app.js 文件,并添加以下代码导入新添加的
mongojs
:var mongojs = require('mongojs');
- 接下来,添加以下行以连接到前面步骤中创建的 MongoDB:
var db = mongojs('mongodb://admin:123456@ds149353.mlab.com:49353/userdb001', ['UserInfo']);
- 现在,我们将创建 User CRUD API 的
routes
,让我们在单独的文件夹中创建它们。右键单击 server 文件夹,选择 **New Folder**,输入名称routes
,然后按 Enter。 - 右键单击新创建的 routes 文件夹,选择 **New File**,输入文件名 user.js,然后按 **Enter** 键。
- 在新建的 user.js 文件中,添加以下代码:
var express = require('express'); var router = express.Router(); var mongojs = require('mongojs'); //Get All Users router.get('/users', function(req, res){ var db = req.app.get("userdb"); db.UserInfo.find(function(err, users){ if(err){ res.send(err); } res.json(users); }); }); // Get Single User router.get('/user/:id', function(req, res, next){ var db = req.app.get("userdb"); db.UserInfo.findOne ({_id: mongojs.ObjectId(req.params.id)}, function(err, task){ if(err){ res.send(err); } res.json(task); }); }); //Save User router.post('/user', function(req, res){ var db = req.app.get("userdb"); var user = req.body; db.UserInfo.save(user, function(err, user){ if(err){ res.send(err); } res.json(user); }) }); // Update User router.put('/user/:id', function(req, res, next){ var db = req.app.get("userdb"); var user = req.body; db.UserInfo.update({_id: mongojs.ObjectId(req.params.id)}, user, {}, function(err, user){ if(err){ res.send(err); } res.json(user); }); }); // Delete User router.delete('/user/:id', function(req, res, next){ var db = req.app.get("userdb"); db.UserInfo.remove({_id: mongojs.ObjectId(req.params.id)}, function(err, user){ if(err){ res.send(err); } res.json(user); }); }); module.exports = router;
- 让我们简要理解一下我们在 user.js 中做了什么。首先,我们导入 Expressjs 来使用
router
,原因非常明显,即使用 API 的路由。接下来,我们导入mongojs
,因为我们在 Get single user、Update 和 Delete User API 中使用它来获取输入的id
参数。如果您看到我们使用了 router 方法get
、post
、put
和delete
,这些是 HTTP 动词,每个函数中的第一个参数是string
route
(您可以使用任何您想要的),第二个参数是带有req
、res
和可选next
参数的回调函数。req
参数是输入请求,其中包含输入参数、主体、头部等。res
是来自服务器的响应。next
参数是什么?自己尝试找到答案。在每个回调函数中,您可以看到语句var db = req.app.get("userdb");
,这是我们在 app.js 中创建的 MongoDB 实例。我只添加了此语句以展示如何将数据/参数从 app.js 发送到 user.js 或任何其他路由。我没有在每个路由中创建 MongoDB 实例并将mLab
连接字符串复制到每个地方(以防您有更多 API 路由),而只是将其保留在 app.js 文件中,并将其暴露为一个参数,以便每个路由都可以从req
对象中使用它。接下来,我们为get
、put
、post
和delete
操作调用相应的 MongoDB 函数,并传递所需的输入变量。 - 接下来,编辑 app.js 文件,并根据以下内容进行更新:
var express = require('express'); var path = require('path'); var bodyParser = require('body-parser'); var users = require('./routes/user'); var mongojs = require('mongojs'); var db = mongojs('mongodb://admin:123456@ds149353.mlab.com:49353/userdb001', ['UserInfo']); var port = 3000; var app = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({extended: false})); app.set("userdb",db); app.use("/api",users); app.listen(port, function(){ console.log('Server started on port '+port); });
- 我们删除了带
string
消息的测试路由,并添加了bodyParser
,这是一个 中间件,并提供以下信息:-
app.use(bodyParser.json())
基本上告诉系统您希望使用 JSON。这仅在我们的POST
请求中的header-type
是 JSON 时才有效。 -
bodyParser.urlencoded({extended: ...})
基本上告诉系统您想使用简单的算法进行浅解析(即false
)还是复杂的算法进行深度解析,能够处理嵌套对象(即true
)。(Stackoverflow 参考)
-
- 接下来,在导入我们新创建的
user
路由文件后,我们添加了app.use("/api",users);
。Expressjs 的use
方法告诉我们的应用程序使用外部路由(在我们的例子中,这些路由在 user.js 文件中定义)。 - 在
app.set("userdb",db);
语句中,我们设置了db
实例变量,该变量与路由一起传递,并且在 user.js 文件中,我们在每个 API 中使用请求的get
方法来使用它。 - 到目前为止,我们已经创建了用户管理 API,让我们在 Postman 中进行测试。Postman 是一个非常易于使用的 API 测试工具,您也可以使用 SOAP UI 或 Fiddler。根据您的操作系统下载并安装 Postman。
- 右键单击 server 文件夹,选择 **Open in Command Prompt**。运行命令:
node app
,并确保您看到消息Server started on port 3000
。 -
在您的应用程序启动并运行后,打开 Postman,并根据以下屏幕截图配置
GET
请求,然后点击 **Send** 按钮。 -
要
POST
新用户,请根据以下屏幕截图配置 Postman(关注红色框),按 **Send** 按钮,并在底部的选项卡中查看response
,您会看到_id
已添加到响应中,请到mLab
的documents
中验证插入是否成功: -
要
PUT
(更新现有用户),请根据以下屏幕截图配置 Postman,请记住,您 URL 中的id
会不同,因此请到mLab
的 documents 中获取您要更新用户的_id
。 -
要
DELETE
用户,请根据以下屏幕截图配置 Postman,请记住,您 URL 中的id
会不同,因此请到mLab
的 documents 中获取您要删除用户的_id
。 - 本篇文章到此结束,您可以进行练习,暴露更多用户 API,更新路由,创建包含不同信息的 MongoDB
documents
,直到您阅读 下一部分。:)
在下一部分
在本篇文章中,我们对 node.js 和 Expressjs 有了基本的了解。我们还设置了开发环境,并在 mLab 上创建了 MongoDB 账户,在 Auth0 上创建了认证和 JWT 账户。最后,我们通过 Expressjs 暴露了用户管理 API,并在 Postman 中进行了测试。
在 下一部分,我们将创建 Angular 4 客户端应用程序,将其与 node.js 集成,并调用用户管理 API 来加载、添加、更新和删除用户。