Dart服务器端 mojito包 原

介绍

现代Web应用程序的微框架,从shelf框架开始构建

就像它的名字一样,Mojito主要是糖和其他成分的混合物。 Mojito故意在几个shelf包上非常薄,并专注于构建应用程序的整体体验。

Mojito的重点是现代富Web应用程序,它们将ui与服务完全分离。 因此,它不捆绑任何服务器端模板包,尽管可以轻松添加。

Mojito的核心架构本身就是shelf。 所有组件都是现有的pub包,它们是从头开始构建的架构组件。 这使得利用将来出现的任何新的基于shelf的包非常容易

用法

入门

要创建Web服务器并在端口9999上启动它,请在文件中键入以下内容并运行它。

import 'package:mojito/mojito.dart';

main() {
  var app = init();
  app.start();
}

你应该看到像这样的输出

2015-06-28 13:03:27.123 [INFO] mojito: Serving at http://:::9999

这不会做任何有趣的事情,因为我们没有添加任何路由。

让我们现在解决这个问题

main() {
  var app = init();

  app.router.get('/hi', () => 'hi');

  app.start();
}

这次当你启动时,你也应该看到类似的东西

2015-06-28 13:06:31.957 [INFO] mojito: GET	->	/hi

用curl试试吧

curl http://localhost:9999/hi

你应该看到'hi'的预期响应

开发模式

Mojito有一个开发模式的概念,有助于快速开发循环。 默认情况下,它将根据环境变量MOJITO_IS_DEV_MODE激活开发模式。 您可以在shell提示符中激活它

export MOJITO_IS_DEV_MODE=true

初始化mojito时,您可以轻松覆盖开发模式的确定方式。 例如

var app = init(isDevMode: () => true);

将它设置为始终打开。 通常你不想这样做。

如果在appengine上运行,则可以使用以下命令设置开发模式。

var app = init(isDevMode: () => Platform.environment['GAE_PARTITION'] == 'dev');

路由

Mojito配备了功能丰富的路由器。 您可以通过调用app.router来访问根路由器。 它支持多种样式来创建路由,例如:

  • 路由注解 @Get('{accountId}') Account find(String accountId) => new Account.build(accountId: accountId);
  • 使用流畅的路由api router.get('{accountId}', (String accountId) => new Account.build(accountId: accountId));
  • 在内置支持CRUD样式方法等

所有方式均支持:

  • 在路由层次结构中的任何位置添加中间件
  • 自动转换 为/到 JSON和Dart类

要更好地了解您拥有的选项,请阅读博客文章中的路由选项

mojito路由扩展了shelf_rest的路由器。 由于这在shelf_rest文档中有详细记载,因此我在此不再重复。

此外,mojito还为以下任务提供路由方法。

静态资源处理

静态资产(如html和css)是大多数Web应用程序的支柱。

在生产中,这些资产是从文件系统提供的,但在开发中,使用pub serve更方便。

Mojito允许您设置一个静态资产处理程序,在开发模式中和生产中的文件系统(有关激活的详细信息,请参阅开发模式一节)使用pub serve,这使得Mojito非常容易。

以下示例为使用/ ui开头的所有请求设置了一个路由,该请求使用pub serve(端口8080)和文件系统路径(build / web)的默认设置。

app.router.addStaticAssetHandler('/ui');

OAuth(1和2)客户端

Mojito路由器提供了设置实现OAuth 2授权代码流的“客户端”部分所需路由的方法以及OAuth1的类似路由

这允许开发人员编写与启用OAuth的服务交互的Web应用程序,例如:

  • google
  • github
  • bitbucket
  • hipchat
  • 许多......

为了进一步简化这一过程,mojito支持多个开箱即用的授权服务器。以下示例显示了在使用memcache存储OAuth2数据在Google Appengine上部署时如何添加github客户端。

final oauth = app.router.oauth;

oauth.gitHub().addClient(
    (_) => new ClientId('your clientId', 'your secret'),
    oauth.storage.memcache(() => context.services.memcache),
    new UriTemplate(
        'http://example.com/loginComplete{?type,token,context}'));

您可以通过调用router.oauth来访问oauth的路由构建器。从那里你可以访问开箱即用的oauth存储(例如memcache和内存中的开发),以及用于常见授权服务器的自定义路由构建器,如github,google和bitbucket(PR欢迎更多服务器)。

对于其他(非开箱即用)授权服务器,请使用oauth.oauth2(...)或oauth.oauth1(...)方法。

当您启动上面的示例时,您将看到为github流创建的两个路由

2015-06-29 08:44:51.503 [INFO] mojito: GET	->	/github/userGrant
2015-06-29 08:44:51.503 [INFO] mojito: GET	->	/github/authToken

userGrant路由是您发送用户浏览器以启动流的位置。 它将重定向到github以供用户授予访问权限,github将把用户重定向回authToken路由。

成功完成身份验证流程后,用户浏览器将重定向回您提供的URL(本示例中为“http://example.com/loginComplete”),并相应地填充type, token 和 context 的查询参数。

在mojito中开始使用oauth的好地方是在mojito的示例文件夹中运行oauth.dart。

这为开箱即用的集成设置了路由。 然后,您可以通过向userGrant网址打开浏览器来尝试它

http://localhost:9999/oauth/github/userGrant
  • 专家提示
  • Mojito使用shelf_oauth来实现oauth流。

上下文

Mojito通过context属性提供一些内容,例如当前登录的用户。 访问只需导入mojito。 例如

import 'package:mojito/mojito.dart';

somefunction() {
  print(context.auth);
}

认证

Mojito通过app.auth公开帮助程序来设置身份验证。 如果要将其应用于所有路由,请使用global构建器。

全局认证

例如,以下内容将应用程序设置为使用基本身份验证,允许通过http进行访问(除了开发之外的一个坏主意)并允许匿名访问。

  app.auth.global
    .basic(_lookup)
    ..allowHttp=true
    ..allowAnonymousAccess=true;

请注意,allowAnonymousAccess实际上是一种授权形式(而不是身份验证),只是一种方便。 有关更多选项,请参阅下面的授权部分。

目前经过身份验证的用户

当前经过身份验证的用户(如果有)可通过mojito上下文获得。

它被定义为一个Option,如果没有当前经过身份验证的用户,则为None,如果有,则为Some。 例如,以下内容获取登录用户的用户名(如果有),或者将其设置为“guest”。

app.router..get('/hi', () {
  var username = context.auth.map((authContext) =>
      authContext.principal.name)
      .getOrElse(() => 'guest');

  return 'hello $username';
});

路由特定认证

要仅对某些路由应用特定身份验证,请使用auth builder()并使用所需路由上的命名参数middleware添加它。

var randomAuthenticator = (app.auth
      .builder()
      .authenticator(new RandomNameAuthenticator())..allowHttp = true).build();

  app.router
    ..get(
        '/randomness',
        () {
          String username = context.auth
              .map((authContext) => authContext.principal.name)
              .getOrElse(() => 'guest');

          return 'who are you today $username';
        },
        middleware: randomAuthenticator);

这里'/ randomness'路由有中间件:randomAuthenticator,它将该认证符应用于路由。

  • 专业提示
  • 如果将身份验证中间件添加到使用router.addAll定义的路由,则它将应用于其所有子路由。
  • 请参阅examples文件夹中的basic_example.dart,了解RandomNameAuthenticator的实现方式
  • mojito使用shelf_auth进行身份验证支持。 有关更多详细信息,请参阅shelf_auth文档

授权

Mojito通过app.authorisation公开帮助设置授权。 与身份验证类似,如果要将其应用于所有路由,请使用全局构建器,否则使用builder()。

以下显示了如何强制只有经过身份验证的用户才能访问特定路由。 这很有用,例如,如果您设置了允许匿名访问的全局身份验证器,并且您希望阻止对某些路由的匿名访问。

app.router.get('privates', () => 'this is only for the privileged few',
        middleware: app.authorisation.builder().authenticatedOnly().build())
  • 专家提示
  • Mojito使用shelf_auth进行授权支持。 有关更多详细信息,请参阅shelf_auth文档

其他中间件

Mojito通过app.middleware公开帮助设置其他中间件。 与身份验证类似,如果要将其应用于所有路由,请使用global构建器,否则使用builder()。

与其它Shelf包集成

它也很容易使用任何未与mojito捆绑的shelf包。

shelf包将暴露一个shelf Handler。 所有主要的mojito路由器方法都采用处理程序参数,因此很大程度上是将Handler从要集成的shelf包中插入到要使用的路由方法中。

如果程序包支持多个http方法,或者它只提供一个设置路径,那么应该使用add方法。

注意:如果您愿意,也可以使用@Add注解

示例 - 集成shelf_rpc

import 'package:mojito/mojito.dart';
import 'package:shelf_rpc/shelf_rpc.dart' as shelf_rpc;
import 'package:rpc/rpc.dart';

main() {

  var app = init();

  var apiServer = <create rpc apiServer somehow>;
  // create a shelf handler from the api
  var handler = shelf_rpc.createRpcHandler(apiServer);

  // create a route for the handler. 
  app.router
    ..add('rpc', null, handler, exactMatch: false);

  app.start();
}

注意exactMatch:false是必需的,因为shelf_rpc提供了许多子路由。 还使用null作为methods参数的值,以便将所有方法传递给api。

在引擎盖下

Mojito捆绑了许多现有的货架库,并将它们集成以便于使用。 这些包括:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏沈唁志

在Ubuntu 16.04上安装Roundcube

Roundcube是一个基于网络的IMAP电子邮件客户端,提供类似于谷歌Gmail的用户界面。它是用PHP编写的服务器端应用程序,旨在访问电子邮件服务器或服务。...

63610
来自专栏difcareer的技术笔记

修改手机的ro.debuggable配置0x01:获取boot.img0x02:修改boot.img0x03:boot.img相关0x04:变砖后的自救

我们自己编译的源码刷机ro.debuggable就是为1,这个时候所有的进程都可以远程调试。但是自己编译的源码里面没有GooglePlay,有些应用的部分功能又...

41730
来自专栏贾鹏辉的技术专栏@CrazyCodeBoy

React Native发布APP之签名打包APK

React Native发布APP之签名打包APK ---- 用React Native开发好APP之后,如何将APP发布以供用户使用呢?一款APP的发布流程...

29050
来自专栏向治洪

认识Kubernates(K8S)

在后端开发中,在介绍Jenkins的可伸缩部署方式上,主要有两种方式:一种是基于Docker(或者docker-swarm 集群)的部署方式,另外一种是基于ku...

85280
来自专栏FreeBuf

新手指南:如何用Ettercap实现“中间人攻击”

什么是“中间人攻击”? 中间人攻击(Man-in-the-Middle Attack,简称“MiTM攻击”)是一种“间接”的入侵攻击,这种攻击模式是通过各种技术...

37070
来自专栏IT笔记

MVC与三层架构有什么区别

首先,声明一下,三层是三层,MVC是MVC,这俩是毫无关系的。 三层是从整个应用程序架构的角度来分的三层(如果程序需要,还可以分多层)。 三层架构通常包括表示层...

37380
来自专栏白驹过隙

Socket编程回顾,一个最简单服务器程序

23230
来自专栏云计算教程系列

如何在FreeBSD 10.1上使用Sendmail通过外部SMTP服务发送电子邮件

设置新的Web服务器时最常见的需求之一是发送电子邮件。最安全,最简单的方法是将服务器连接到SendGrid或Amazon SES等邮件服务。使用外部服务将帮助您...

23600
来自专栏Java编程技术

UML建模(组件图)

组件图是为了展示组元(components),组元提供的接口(provided inerfaces)和需要调用的接口(required interfaces),...

81820
来自专栏Seebug漏洞平台

Struts2 REST 插件 XStream 远程代码执行漏洞 S2-052(CVE-2017-9805)

漏 洞 概 述 1. 漏洞信息: 2017年9月5日,Apache Struts 发布最新安全公告。Apache Struts2 的 REST 插件存在远程...

30860

扫码关注云+社区

领取腾讯云代金券