首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

使用 Play Framework 和 Scala 管理用户身份验证(1)

使用 Play Framework 和 Scala 管理用户身份验证(1)

在现代 Web 应用程序中实现身份验证可能需要大量的工作。您需要使用户能够通过多种机制(凭据;使用 OAuth1、OAuth2 或                OpenID                的社交服务提供商)执行身份验证。用户注册和密码重置通常需要基于电子邮件的流。请求和查看也必须知道登录用户的身份(如果有)。
本教程介绍一个使用                  构建的入门级身份验证应用程序。Play 是   新一代反应式                Web 框架(比如 Node.js 和 Vert.x)中的一员。Play                还带来了开发友好的特性,比如原生的                XML 和 JSON 处理,开发模式下的浏览器内错误报告,内置的测试帮助器,以及 Selenium 集成。您可在 Java™ 或                Scala 中编写 Play 应用程序,但首选 Scala。函数语言最适合反应式编程风格。尽管 Java 最终在第 8                版中接受了函数编程概念,但它落后于 Scala 丰富的函数特性储备。
我的入门级应用程序通过实现以下功能展示了 Scala 和 Play 的实际运用:
Play 的可伸缩性通过使用异步 I/O,Play 采取了一种编程模型,其中应用程序代码对在 I/O                    完成时触发的事件做出反应。在此期间,运行应用程序代码的线程不会拦截,而能够处理其他请求。此设计支持高效地使用处理器核心:Play                    可使用少量线程处理大量的流量。而且 Play                    不会存储任何服务器端会话状态,它通过消除会话亲缘性而帮助实现了水平可伸缩性:集群中的任何服务器都可受理一个请求。

  • 基于电子邮件的用户注册
  • 凭据(电子邮件和密码)和通过 OAuth1 进行的 Twitter 身份验证
  • 基于电子邮件的密码重置
  • 凭据和 Twitter 帐户链接
  • 用户感知的视图、HTTP 请求和 Ajax 调用的示例
该应用程序使用   执行身份验证工作,使用   实现用户持久性。所有请求处理和与 MongoDB                的交互都是完全异步的。您可使用此应用程序作为您自己的项目的起点,省得自己从头实现身份验证。
我假设您基本熟悉 Scala 语言。(如果您拥有 Java 背景且需要了解 Scala,我建议您阅读 developerWorks   系列。)我还假设您至少拥有最基本的 Play                经验;拥有控制器、路由和视图的基本知识就足够了。有关 Play 的介绍,请参阅   的 “入门” 小节。(本教程的代码使用 Play Framework 2.4.2                版,所以请阅读该版本的文档。)一定要查阅本系列的  ,我将在其中展示如何将 Play 应用程序部署在 IBM Bluemix™ 上。
设置Play 的应用采用 Play 的公司包括  、  和  。撰写本文时,该项目在 GitHub 上已有 2,411 个分支,Stack Overflow 上有                    10,308 个带 playframework 标记的问题。

要构建和运行这个入门级应用程序,您需要在系统上安装 Play 2.4.2 或更高版本和 MongoDB。
安装 MongoDB 和 Play 按照 MongoDB 网站的                  小节中针对您平台的说明,安装 MongoDB。在大多数 Linux 发行版上,您可使用相应的包管理器安装 MongoDB。对于                Mac,您可使用                Homebrew;对于 Windows,可使用 MSI 安装程序。
Play Framework(自 2.4.0 版开始)需要 Java 8,所以请确保您安装了 Java SE 8 SDK。要安装 Play,请   并解压极小的激活程序 — 一个 1MB 的 ZIP 文件,包含将在第一次运行时下载 Play                的代码和依赖项(约 450MB)的启动脚本。为方便起见,您可能希望将激活程序的文件夹添加到您的系统路径中。
下载和运行应用程序 示例应用程序项目托管在   上。您可克隆该项目的 Git 存储库(必须首先登录或注册)来获取源代码。也可参阅   来获取应用程序的 ZIP 文件。拥有代码后,执行以下步骤来运行该应用程序:
  • 在   网站上注册一个应用程序。输入                    http://dwdemo.com:9000/auth/social/twitter 作为回调 URL。
  • 将 127.0.0.1 dwdemo.com 添加到您的 hosts 文件中,以便该应用程序可被在 Twitter                    上注册的同一个域找到。
  • 通过将来自 Twitter 应用程序页上的相应值复制到 conf/silhouette.conf 文件中的第 28 和 29                    行,设置用户密钥和用户机密属性。
  • 运行 mongod --dbpath folder 来启动 MongoDB 服务器,其中                    folder 是 MongoDB 将存储数据库文件的目录。
  • 要启动该应用程序,转到您克隆了代码的根文件夹并对它执行 activator run。
应用程序启动(首次执行这一步将需要一些时间)后,转到 http://dwdemo.com:9000                来打开它。您会看到一个欢迎屏幕,用户可在其中注册来在应用程序中创建一个帐户。
应用程序配置设置好您的环境后,就可以钻研应用程序配置了。
主要配置文件 主要配置文件是 conf/application.conf,这是 Play 寻找配置属性的默认位置。清单 1 显示了相关部分。               
清单 1. conf/application.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
play.modules.enabled += "play.modules.reactivemongo.ReactiveMongoModule"
play.modules.enabled += "module.Module"

mongodb.uri = "mongodb://localhost:27017/demodb"

mail.from="dwplaydemo <mailrobot@dwplaydemo.net>"
mail.reply="No reply <noreply@dwplaydemo.net>"

play.mailer {
  mock = true
  host = localhost
}

play.http.filters = "utils.Filters"
play.http.errorHandler = "utils.ErrorHandler"

include "silhouette.conf"




application.conf 文件声明两个配置依赖注入绑定的类。ReactiveMongoModule 使反应式                Mongo 绑定可注入到应用程序类中。module.Module 类指定应用程序的注入绑定,主要针对 Silhouette                类。mongodb.uri 属性定义如何连接到 MongoDB,play.mailer                设置一个模拟邮件服务,用于在开发模式下测试注册和密码重置流。一个模拟的邮件收发器将电子邮件记录到控制台;在生产中,该应用程序必须使用一个 SMTP                服务器。
utils.Filters                类定义应用程序的过滤器管道。目前,这个类使用                Play 的跨站请求伪造                (CSRF)                过滤器来保护 POST 请求。utils.ErrorHandler                类拥有设置应用程序全局请求错误处理策略的作用;它为内部服务器和页面未找到条件定义错误页面重定向。更重要的是,对于对受保护资源的未授权或未验证的访问尝试,该类还定义了向登录页面的重定向。包含的                silhouette.conf 文件声明了特定于 Silhouette 的设置。我将在 “ ” 一节中介绍这些设置。
应用程序路由 conf/routes 文件定义了特定于应用程序的页面的路由和身份验证流。 清单 2                显示了特定于应用程序的路由。
清单 2. 特定于应用程序的路由
1
2
3
4
5
6
7
8
9
10
# Application
GET     /                           controllers.Application.index
GET     /profile                    controllers.Application.profile

# Rest api
GET     /rest/profile               controllers.RestApi.profile

# Public assets
GET     /assets/*file               controllers.Assets.versioned(path="/public", file: Asset)
GET     /webjars/*file              controllers.WebJarAssets.at(file)




                该应用程序包含两个页面。索引页面是用户感知的,适用于登录的用户或匿名访问。概况页面是受保护的,需要授权才能访问(否则,它会重定向到索引页面)。/rest/profile                URL 映射到一个安全的 REST API 端点,该端点以 JSON 格式返回登录用户的概况信息。最后两个 URL                是公共资产的标准路由,比如样式表、图像和 JavaScript 代码。 清单 3 显示了身份验证路由和流。
清单 3. 身份验证路由
1
2
3
4
5
6
7
8
9
10
11
12
13
GET     /auth/signup                controllers.Auth.startSignUp
POST    /auth/signup                controllers.Auth.handleStartSignUp
GET     /auth/signup/:token         controllers.Auth.signUp(token:String)

GET     /auth/reset                 controllers.Auth.startResetPassword
POST    /auth/reset                 controllers.Auth.handleStartResetPassword
GET     /auth/reset/:token          controllers.Auth.resetPassword(token:String)
POST    /auth/reset/:token          controllers.Auth.handleResetPassword(token:String)

GET     /auth/signin                controllers.Auth.signIn
POST    /auth/authenticate          controllers.Auth.authenticate
GET     /auth/social/:providerId    controllers.Auth.socialAuthenticate(providerId:String)
GET     /auth/signout               controllers.Auth.signOut




注册流从对注册页面的 GET 请求开始。从该页面,用户通过 POST                将他们的注册信息(电子邮件地址、密码、姓名)提交给                /auth/signup。应用程序通过发送一封电子邮件来处理该提交,邮件中包含一个                /auth/signup/:token URL,用户必须访问该 URL 才能完成注册操作。密码重置流类似:用户通过                GET 获取密码重置页面,他们在其中通过 POST 将一个电子邮件地址提交给                /auth/reset。此提交会生成一封包含一个 /auth/reset/:token URL                的电子邮件。这个 URL 将用户带到一个页面,他们可在其中输入一个新密码并通过 POST 将其提交到                /auth/reset/:token 来完成该过程。
/auth/signin 路由提供了访问登录页面的路径。auth/authenticate                路由是执行凭据验证的 URL 端点,/auth/social/:providerId                是执行社交验证的端点。目前,唯一受支持的社交服务提供商是                Twitter,通过 OAuth1 实现。/auth/signout 路由公开用于从应用程序注销的端点。
返回列表