65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2017年8月20日

CPOL

15分钟阅读

viewsIcon

25324

downloadIcon

332

MEAN Stack,开发环境搭建,Expressjs API 开发与测试

文章系列

引言

在本系列短文中,我将通过开发我们最喜欢的 用户管理 应用,一步步讲解使用 MEAN Stack(结合 Angular 4)的应用开发。之后,我们将使用 Auth0 添加用户认证,并通过 JWT (JSON Web Token) 授权我们的 RESTful API 请求。我们将在 Visual Studio Code 编辑器中开发我们的应用。

背景

虽然这是一个独立的系列文章,但最好您先阅读 用户管理 这篇文章。我们将使用与用户管理几乎相同的 Angular 2/4 代码,只是通过 Angular CLI 命令创建组件、服务、模块等。

MEAN 代表 MongoExpressjsAngularNode.js。对这些技术有基本了解会很有帮助,但并非必需。我将在开发过程中简要解释每种技术。

我们将开发什么以及如何开发?

我们将从 这里 下载用户管理(添加/更新/删除/加载)应用。我们将下载 node.js、Visual Studio Code,通过 node.js NPM 安装 Angular CLI,在 Auth0 上创建账户以用于认证,并在 mLab 上创建 MongoDB,我们将在这里存储用户信息,而不是使用 SQL 数据库。

以下是我们即将执行的步骤总结

  • 安装所有必需软件并创建 Auth0mLab 账户。
  • 创建一个新项目并在 Visual Studio Code 中打开项目。
  • 创建 Node.js 服务器,连接到 mLab 并通过 Expressjs 暴露用户 CRUD RESTful API。
  • 通过 Angular CLI 命令根据 用户管理应用创建所需的组件、服务和路由。
  • 更新 Angular 客户端应用以调用 Expressjs 暴露的 RESTful API。
  • 验证应用功能。
  • 添加登录功能,实现 AuthGuard 以保护用户管理页面路由。
  • 在 Angular 客户端和 Expressjs 服务器端实现 JWT,以保护数据通信。简单来说,Angular 客户端会在 GETPOSTPUTDELETE 请求中发送 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** 按钮。输入 EmailPassword,或使用 Github、Google 或 Microsoft 账户注册。随您选择。注册后,系统会要求您输入 ACCOUNT NAME,输入任何唯一的名称,然后点击底部的 **Next** 按钮。在下一页输入具有描述性的信息,然后点击 **Create Account** 按钮。您将收到一封验证邮件到您注册时使用的电子邮件地址。点击邮件中的 **Verify Your Account** 按钮或链接,使用您的凭证登录,您将被重定向到一个页面,显示验证成功和 21 天试用期信息。目前就这些,先放到这里,我们稍后再回来。
  • 访问 https://mlab.com/ 网站,点击右角的 **SIGN UP** 按钮。输入新账户信息,然后点击 **Create Account** 按钮。您将收到一封验证邮件到您注册时使用的电子邮件地址。点击邮件中的 **Verify Your Account** 链接,使用您的凭证登录,您将被重定向到一个验证成功的页面。先放到这里,我们稍后再回来创建 collectiondocuments
  • 环境搭建就到这里,我们将在应用中通过 npm (Node Package Manager) 添加 Angular 和 node.js 所需的客户端包。

开始吧

  1. 创建项目文件夹 mean-example,并在其中创建两个文件夹:serverclient。在 server 文件夹中,我们将创建一个 node.js 应用,连接到 mLab 网站(用于 MongoDB),通过 Expressjs 创建用户 CRUD RESTful API。在 client 文件夹中,我们将存放 Angular 代码,该代码将调用 Expressjs API 并在浏览器中渲染视图。
  2. 接下来,打开 Visual Studio Code,选择 **File -> Open Folder...**。选择新创建的 mean-example 文件夹,然后点击 **Select Folder** 按钮。
  3. 您将在 **EXPLORER** 面板中看到两个空文件夹:clientserver。(如果 Explorer 不可见,请选择顶部菜单 **View -> Explorer**)。
  4. 首先,让我们创建服务器端应用。如前所述,我们将使用 node.js 和 Expressjs 开发服务器端应用,但在开始开发之前,让我们先了解一下 node.js 和 Expressjs。
    1. Node.js:您会在网上找到很多花哨的定义,但简单来说,它是一个用 JavaScript 编写的应用和网站的服务器端框架,速度快且非阻塞。如何做到的?仅为理解,当它执行任何任务时,它不会停在那里等待完成,而是会向其注册一个回调函数,然后继续执行下一任务。当前任务完成后,它会调用回调函数通知其完成,依此类推。这使得 node.js 成为事件驱动的,就像事件将在一次(当 Node 准备好调用回调时)触发,回调充当事件处理程序。现在 node.js 本身的功能很薄弱,因此我们有很多库/模块可以导入到 node.js 应用中以执行所需的功能。其中之一就是 Expressjs。
    2. Expressjs:一个用于 Web 应用、RESTful API 的 node.js 框架,您还可以在其中定义 路由。Expressjs 灵活支持任何 模板 框架(HTML 或视图文件),例如 JadePugEJS。由于我们使用 Angular 4 作为客户端,并且不在服务器端创建任何模板/视图,所以目前不用担心任何模板框架。我们将仅使用 EJS 来渲染我们的 HTML。我们的 Expressjs 将指向 dist 文件夹,该文件夹将在我们使用 Angular CLI build 命令构建 Angular4 客户端后生成(稍后我们将简要介绍)。
  5. 虽然您可以使用 Express Application Generator CLI 来生成 Express 服务器、pug 视图、路由、文件夹等。但我将手动创建所需的文件,因为我只需要少量文件。您可以自行尝试 Express CLI。
  6. 右键单击 server 文件夹,选择 **New File**。输入文件名 app.js。这将是我们的 node.js 服务器文件。

  7. 接下来,我们将通过 npm 获取 Expressjs 模块。我将单独保留服务器和客户端的 package.json 文件。右键单击 **EXPLORER** 面板中的 server 文件夹,选择 **Open in Command Prompt**。首先,我们将在 server 文件夹中创建 package.json 文件。在命令提示符中输入命令 npm init 并按 **Enter**,它会询问一些信息,例如应用程序名称、作者、描述等。在此处添加或一直按 Enter,最后按 yes。您将在 server 文件夹中找到已创建的 package.json 及其基本结构,很好。
  8. 输入以下命令安装 Expressjs:npm install express --save。检查 package.json 文件,在 **dependencies** 部分,您会找到 "express": "^4.15.4"(或任何更新版本)。
  9. 接下来,在命令提示符中运行 npm install body-parser --save & npm install ejs --save 命令。我们已经讨论过 EJS,它是您可以在 Expressjs 中使用的 JavaScript 模板,用于渲染视图。
  10. 编辑 app.js 文件,暂时添加所需的外部模块 expresspathbodyparser
    //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');
  11. 接下来,添加以下代码
    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);
    });
  12. 上面的代码非常自 explanatory,我们指定了应用程序端口,创建了 expressjs 实例。在下一条语句中,我们指定如果有一个未指定路由的 localhost URL,则只向浏览器发送文本 "I am up & running at port: 3000"。Express 的 use 方法允许我们的应用程序使用外部路由作为应用程序的一部分。app.listen 将打开/使用指定的端口 (3000) 用于 localhost。确保此端口未被任何其他进程使用。您可以指定任何可用端口。
  13. 右键单击 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 消息。很酷,这是快速测试服务器设置的方法。
  14. 下一步是在 MongoDB 中设置 User 数据库,并在 Expressjs 中暴露 RESTful CRUD API。打开 https://mlab.com 网站,使用上一步创建的凭证登录。登录后,您将进入以下页面:

  15. MongoDB Deployment section 的顶部,点击 **Create New** 按钮。在下一个屏幕中,选择 **Plan Type SANDOX**。点击 **SANDOX** 后,底部会出现 **Continue** 按钮,点击它。

  16. 由于这个免费数据库将在 AWS 上创建,下一个屏幕会要求您选择 AWS 区域,选择您最近/所需的区域。我在弗吉尼亚州,所以我将选择 US East (Virginia),选择 **Region** 后,点击底部的 **Continue** 按钮。

  17. 输入数据库名称 userdb001 ,然后点击底部的 **Continue** 按钮。

  18. 点击底部的 **Submit Order** 按钮。

  19. 片刻之后,您将进入主页,您的数据库已可用并准备就绪。

  20. 在上图中,点击以 ds149353... 开头的新创建的行,您将进入以下屏幕。此页面包含重要信息,例如 MongoDB URI,我们将通过它从 node.js 连接到 MongoDB。其他信息是关于数据库 CollectionsUsersBackups 等。目前我们将使用 **Collections** 和 **Users** 选项卡。
    1. Collections:您可以在线获取 MongoDB Collections 的定义,但由于我不是定义的忠实粉丝。仅为理解,请将 Collection 视为关系数据库的 。就像关系数据库 可以有多个行一样,在 MongoDB 中,一个 Collection 可以有多个 documents,当然,您可以根据需要创建任意数量的 Collections
    2. DocumentDocument 只是一个 JSON 数据文件(键、值)对。我们将在后续步骤中看到 document 的确切外观。

  21. 点击 **Add Collection** 按钮,在弹出模态框中,输入 **Collection name** 为 UserInfo,然后点击 **Create** 按钮。

  22. 太棒了,让我们创建一个示例文档,点击 UserInfo collection(红色区域)。您将进入以下屏幕。点击 **Add document** 按钮。

  23. 您将进入以下编辑器,现在根据第二个截图在 **Create Document** 编辑器中添加 JSON 数据,然后点击 **Create and go back**。

  24. 太好了!您会看到新的 JSON document 已创建,并且有一个自动分配的唯一 _id,这是一个很棒的功能。

  25. 接下来,让我们创建数据库 User,点击上一步截图顶部的 userdb001。点击 **Users** 选项卡,然后点击 **Add database user**,输入用户名 admin 和密码 123456。(或者您喜欢的任何内容,但请记住它)。点击 **Create** 按钮。

  26. 这就是我们在 mLab 网站上需要做的全部,记下 **To connect using a driver via the standard MongoDB URI** 的值。对您来说,这个值会不同。我们需要它来从 node.js 连接 MongoDB。
  27. 现在让我们回到 node.js,我们需要 mongojs 包来从 mLab 网站连接到 MongoDB。重复相同的步骤,如果您的命令提示符尚未打开,右键单击 server 文件夹并选择 **Open in Command Prompt**,输入命令 npm install mongojs --save
  28. 编辑 server 文件夹中的 app.js 文件,并添加以下代码导入新添加的 mongojs
            var mongojs = require('mongojs');
  29. 接下来,添加以下行以连接到前面步骤中创建的 MongoDB:
            var db = mongojs('mongodb://admin:123456@ds149353.mlab.com:49353/userdb001', ['UserInfo']);
  30. 现在,我们将创建 User CRUD API 的 routes,让我们在单独的文件夹中创建它们。右键单击 server 文件夹,选择 **New Folder**,输入名称 routes,然后按 Enter。
  31. 右键单击新创建的 routes 文件夹,选择 **New File**,输入文件名 user.js,然后按 **Enter** 键。
  32. 在新建的 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;
  33. 让我们简要理解一下我们在 user.js 中做了什么。首先,我们导入 Expressjs 来使用 router,原因非常明显,即使用 API 的路由。接下来,我们导入 mongojs,因为我们在 Get single user、Update 和 Delete User API 中使用它来获取输入的 id 参数。如果您看到我们使用了 router 方法 getpostputdelete,这些是 HTTP 动词,每个函数中的第一个参数是 string route(您可以使用任何您想要的),第二个参数是带有 reqres 和可选 next 参数的回调函数。req 参数是输入请求,其中包含输入参数、主体、头部等。res 是来自服务器的响应。next 参数是什么?自己尝试找到答案。在每个回调函数中,您可以看到语句 var db = req.app.get("userdb"); ,这是我们在 app.js 中创建的 MongoDB 实例。我只添加了此语句以展示如何将数据/参数从 app.js 发送到 user.js 或任何其他路由。我没有在每个路由中创建 MongoDB 实例并将 mLab 连接字符串复制到每个地方(以防您有更多 API 路由),而只是将其保留在 app.js 文件中,并将其暴露为一个参数,以便每个路由都可以从 req 对象中使用它。接下来,我们为 getputpostdelete 操作调用相应的 MongoDB 函数,并传递所需的输入变量。
  34. 接下来,编辑 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);
    });
  35. 我们删除了带 string 消息的测试路由,并添加了 bodyParser,这是一个 中间件,并提供以下信息:
    1. app.use(bodyParser.json()) 基本上告诉系统您希望使用 JSON。这仅在我们的 POST 请求中的 header-type 是 JSON 时才有效。

    2. bodyParser.urlencoded({extended: ...}) 基本上告诉系统您想使用简单的算法进行浅解析(即 false)还是复杂的算法进行深度解析,能够处理嵌套对象(即 true)。(Stackoverflow 参考

  36. 接下来,在导入我们新创建的 user 路由文件后,我们添加了 app.use("/api",users); 。Expressjs 的 use 方法告诉我们的应用程序使用外部路由(在我们的例子中,这些路由在 user.js 文件中定义)。
  37. app.set("userdb",db); 语句中,我们设置了 db 实例变量,该变量与路由一起传递,并且在 user.js 文件中,我们在每个 API 中使用请求的 get 方法来使用它。
  38. 到目前为止,我们已经创建了用户管理 API,让我们在 Postman 中进行测试。Postman 是一个非常易于使用的 API 测试工具,您也可以使用 SOAP UI 或 Fiddler。根据您的操作系统下载并安装 Postman
  39. 右键单击 server 文件夹,选择 **Open in Command Prompt**。运行命令:node app ,并确保您看到消息 Server started on port 3000
  40. 在您的应用程序启动并运行后,打开 Postman,并根据以下屏幕截图配置 GET 请求,然后点击 **Send** 按钮。

  41. POST 新用户,请根据以下屏幕截图配置 Postman(关注红色框),按 **Send** 按钮,并在底部的选项卡中查看 response,您会看到 _id 已添加到响应中,请到 mLabdocuments 中验证插入是否成功:

  42. PUT(更新现有用户),请根据以下屏幕截图配置 Postman,请记住,您 URL 中的 id 会不同,因此请到 mLab 的 documents 中获取您要更新用户的 _id

  43. DELETE 用户,请根据以下屏幕截图配置 Postman,请记住,您 URL 中的 id 会不同,因此请到 mLab 的 documents 中获取您要删除用户的 _id

  44. 本篇文章到此结束,您可以进行练习,暴露更多用户 API,更新路由,创建包含不同信息的 MongoDB documents,直到您阅读 下一部分。:)

在下一部分

在本篇文章中,我们对 node.js 和 Expressjs 有了基本的了解。我们还设置了开发环境,并在 mLab 上创建了 MongoDB 账户,在 Auth0 上创建了认证和 JWT 账户。最后,我们通过 Expressjs 暴露了用户管理 API,并在 Postman 中进行了测试。

下一部分,我们将创建 Angular 4 客户端应用程序,将其与 node.js 集成,并调用用户管理 API 来加载、添加、更新和删除用户。

历史

MEAN Stack 结合 Angular 4、Auth0 认证及 JWT 授权 - 第一部分 - CodeProject - 代码之家
© . All rights reserved.