素材巴巴 > 程序开发 >

MEAN全栈开发 之 用户认证篇

程序开发 2023-09-24 22:05:49

作者:Soaring_Tiger
http://blog.csdn.net/Soaring_Tiger/article/details/51418209
本篇将覆盖以下内容(阅读本文需要有一定Express、Mongoose基础):

  1. 在 MEAN全栈开发中添加用户认证
  2. 在Express中使用Passport模块管理用户认证
  3. 在Exrpess中生成JSON Web Tokens(JWT)
  4. 实现用户注册与登录
  5. 在Angular当中使用 local storage管理用户session

1.1 在MEAN开发中如何实现用户认证?

对于Angular这样的单页面程序(SPA)而言,用户认证似乎是个麻烦事情,因为所有的(前端)程序都会被发送到浏览器上,所以怎样隐藏你想要隐藏的东西是个问题。

1.1.1我们先来看看传统的基于服务端的程序是如何实现的?

如果你比较熟悉传统的基于服务端的Web开发(比如世界上最好的语言PHP),那么你可能会对单页面应用(SPA)如何实现用户认证感到困惑。
传统的基于服务端的Web开发的用户认证流程一般是这样的:
(1)用户在表单上输入用户名与密码并提交到服务器;
(2)服务器上的程序会通过数据库校验用户名和密码以及权限是否正确;
(3)如果校验成功,服务器在用户的session上做标记并告诉用户他已经登录成功了;
(4)在用户浏览页面的时候,浏览器会将cookie发送到服务端,服务端会校验用户的session以及浏览权限,并将页面返回给用户。
那么,像MEAN全栈开发模式下又该怎么做呢?

1.1.2 MEAN全栈的用户认证实现方式

MEAN全栈的用户认证面临着两个问题:

  1. 通过Express实现的API是无状态的,也就是没有用户session的概念。
  2. 单页面程序(SPA)的编程逻辑已经传送到浏览器了,所以你无法限制这些已经在浏览器端的代码。

符合逻辑的解决方案是在浏览器端保持某种用户session状态,让前端程序决定什么可以显示给用户、什么不能显示给用户,这与服务端控制的方式有所区别,但是这是最主要的变化所在。
一个比较好并且安全的办法是采用JSON Web Token(JWT)来在客户端保存用户数据。对于JWT的细节我们在后面再谈,现在你只要知道它是一个加密了的JSON对象就行了。

管理登录流程

图5 JWT登录流程示意图图5
图5 示意了一个登录流程:(1)用户通过API把其身份验证信息提交给服务器;(2)服务器通过数据库校验用户身份信息;(3)服务器将一个令牌(token)返回给客户端;(4)客户端将令牌(token)保存并在下次需要时使用。
其实,整个流程与传统的服务器实现方案很相似,只是把用户session存在了客户端上。

依靠用户认证信息展示内容

图6:依靠JWT里的信息,SPA能够决定用户可以看到什么信息图6
如图6所示,在用户会话过程当中(user session),当用户要看新的页面的时候,前端程序根据JWT中保留的信息就能判断用户是否有权限进行浏览。
比起传统实现方法不同的是,除非用户需要通过API获取数据库里的信息,否则MEAN的服务端不用关心用户在看什么东西。

安全的调用API

如果应用程序的某些部分是对特定用户设限的,那么对于无状态的API而言,对API的每一次调用都需要知道调用权限,这个时候JWT就派上用场了。如图7所示,在调用需要认证的API端点时,客户端会发送JWT,而服务端通过解码JWT来验证用户的请求。
图7:在调用需要认证的API端点时,客户端会发送JWT,而服务端通过解码JWT来验证用户的请求 图7

ok,上面的部分介绍完了基本概念,我们已经大致上知道要干些什么了。下面我们就要一步步的实现这些过程。

2. 建立用于MongoDB的用户数据模型 (User Schema)

用户名和密码通常存储在数据库当中,在MEAN全栈开发里我们需要通过Mongoose来建一个模。特别需要提醒的是:密码在数据库中一定不要用明文保存!,因为这会带来巨大的安全漏洞。

2.1 单向密码加密:哈希+盐

要提高密码的安全度有一个办法:对密码进行单向加密。单向加密可以防止任何人解密,同时又非常容易验证密码。当用户进行登录的时候,程序可以对密码进行加密,并且比对已经存好的值。
当然,如果只是简单的加密还是不够的,因为如果有很多人用了同样的密码(比如:123456),那么加密出来的字符串就会一模一样,而黑客也就能轻易的对弱密码找出加密的模式。
这个时候就需要靠“盐(Salt)”来帮忙了,所谓“盐”就是一个在用户密码被加密之前针对每一个用户随机生成的字符串,而与密码混合生成的结果就是“哈希(Hash)”,如图8所示。
图8:哈希+盐 过程图8
“盐”和“哈希”被一同存储在数据库当中,而不是仅仅一个“password”字段,通过以上过程,所有的“哈希”都是独一无二的,这样就很好的保护了密码。

2.2 创建Mongoose模型


标签:

上一篇: angular js 自学笔记(一) 下一篇:
素材巴巴 Copyright © 2013-2021 http://www.sucaibaba.com/. Some Rights Reserved. 备案号:备案中。