Pomelo 一

导言##一直对http 的头认证有兴趣,就是路由器的那种弹出对话框输入账号密码怎么实现一直不明白,最近,翻了一下http 协议,发现这是一个RFC 2617的实现,所以写篇文章介绍一下吧.

Http基本认证###这是一个用于web浏览器或其他客户端在请求时提供用户名和密码的登录认证,要实现这个认证很简单:

我们先来看下协议里面怎么定义这个认证的.
编码: 将用户名 追加一个 冒号(‘:’)接上密码,把得出的结果字符串在用Base64算法编码.

请求头: Authorization: 认证类型 编码字符串

来看一下客户端如何发起请求例如,有一个用户名为:tom, 密码为:123456 怎么认证呢?
步骤如下
编码
Base64(‘tom:123456’) == dG9tOjEyMzQ1Ng==;

把编码结果放到请求头当中
Authorization: Basic dG9tOjEyMzQ1Ng==

请求样例客户端
123

GET / HTTP/1.1Host: localhostAuthorization: Basic dG9tOjEyMzQ1Ng

服务端应答
1234

HTTP/1.1 200 OKDate: Thu, 13 Jun 2013 20:25:37 GMTContent-Type: application/json; charset=utf-8Content-Length: 53

如果没有认证信息
123

HTTP/1.1 401 Authorization RequiredDate: Thu, 13 Jun 2013 20:25:37 GMTWWW-Authenticate: Basic realm="Users"

验证失败的时候,响应头加上WWW-Authenticate: Basic realm=”请求域”.
这种http 基本实现,几乎目前所有浏览器都支持.不过,大家可以发现,直接把用户名和密码只是进行一次base64 编码实际上是很不安全的,因为对base64进行反编码十分容易,所以这种验证虽然简便,但是很少会在公开访问的互联网使用,一般多用在小的私有系统,例如,你们家里头的路由器,多用这种认证方式.

Http 摘要认证###这个认证可以看做是基本认证的增强版本,使用随机数+密码进行md5,防止通过直接的分析密码MD5防止破解.摘要访问认证最初由 RFC 2069 (HTTP的一个扩展:摘要访问认证)中被定义加密步骤:

[图片上传中。。。(1)]

后来发现,就算这样还是不安全(md5 可以用彩虹表进行攻击),所以在RFC 2617入了一系列安全增强的选项;“保护质量”(qop)、随机数计数器由客户端增加、以及客户生成的随机数。这些增强为了防止如选择明文攻击的密码分析。

如果 qop 值为“auth”或未指定,那么 HA2 为

如果 qop 值为“auth-int”,那么 HA2 为
[图片上传中。。。(6)]

如果 qop 值为“auth”或“auth-int”,那么如下计算 response:

如果 qop 未指定,那么如下计算 response:

好了,知道加密步骤,下面我们用文字来描述一下;
最后,我们的response 由三步计算所得.
对用户名、认证域(realm)以及密码的合并值计算 MD5 哈希值,结果称为 HA1。
HA1 = MD5( “tom:Hi!:123456” )
= d8ae91c6c50fabdac442ef8d6a68ae8c

对HTTP方法以及URI的摘要的合并值计算 MD5 哈希值,例如,”GET” 和 “/index.html”,结果称为 HA2。
HA2 = MD5( “GET:/“ ) = 71998c64aea37ae77020c49c00f73fa8

最后生成的响应码
Response = MD5(“d8ae91c6c50fabdac442ef8d6a68ae8c:L4qfzASytyQJAC2B1Lvy2llPpj9R8Jd3:00000001:c2dc5b32ad69187a:auth:71998c64aea37ae77020c49c00f73fa8”) = 2f22e6d56dabb168702b8bb2d4e72453;

RFC2617 的安全增强的主要方式:
发起请求的时候,服务器会生成一个密码随机数(nonce)(而这个随机数只有每次”401”相应后才会更新),为了防止攻击者可以简单的使用同样的认证信息发起老的请求,于是,在后续的请求中就有一个随机数计数器(cnonce),而且每次请求必须必前一次使用的打.这样,服务器每次生成新的随机数都会记录下来,计数器增加.在RESPONSE 码中我们可以看出计数器的值会导致不同的值,这样就可以拒绝掉任何错误的请求.
请求样例(服务端 qop 设置为”auth”)
客户端 无认证
12

GET / HTTP/1.1Host: localhost

服务器响应(qop 为 ‘auth’)
123

HTTP/1.1 401 Authorization RequiredDate: Thu, 13 Jun 2013 20:25:37 GMTWWW-Authenticate: Digest realm="Hi!", nonce="HSfb5dy15hKejXAbZ2VXjVbgNC8sC1Gq", qop="auth"

客户端请求(用户名: “tom”, 密码 “123456”)
123456789

GET / HTTP/1.1Host: localhostAuthorization: Digest username="tom", realm="Hi!", nonce="L4qfzASytyQJAC2B1Lvy2llPpj9R8Jd3", uri="/", qop=auth, nc=00000001, cnonce="c2dc5b32ad69187a", response="2f22e6d56dabb168702b8bb2d4e72453"

服务端应答
1234

HTTP/1.1 200 OKDate: Thu, 13 Jun 2013 20:25:37 GMTContent-Type: application/json; charset=utf-8Content-Length: 53

注意qop 设置的时候慎用:auth-int,因为一些常用浏览器和服务端并没有实现这个协议.##导言##一直对http 的头认证有兴趣,就是路由器的那种弹出对话框输入账号密码怎么实现一直不明白,最近,翻了一下http 协议,发现这是一个RFC 2617的实现,所以写篇文章介绍一下吧.

Http基本认证###这是一个用于web浏览器或其他客户端在请求时提供用户名和密码的登录认证,要实现这个认证很简单:

我们先来看下协议里面怎么定义这个认证的.
编码: 将用户名 追加一个 冒号(‘:’)接上密码,把得出的结果字符串在用Base64算法编码.

请求头: Authorization: 认证类型 编码字符串

来看一下客户端如何发起请求例如,有一个用户名为:tom, 密码为:123456 怎么认证呢?
步骤如下
编码
Base64(‘tom:123456’) == dG9tOjEyMzQ1Ng==;

把编码结果放到请求头当中
Authorization: Basic dG9tOjEyMzQ1Ng==

请求样例客户端
123

GET / HTTP/1.1Host: localhostAuthorization: Basic dG9tOjEyMzQ1Ng

服务端应答
1234

HTTP/1.1 200 OKDate: Thu, 13 Jun 2013 20:25:37 GMTContent-Type: application/json; charset=utf-8Content-Length: 53

如果没有认证信息
123

HTTP/1.1 401 Authorization RequiredDate: Thu, 13 Jun 2013 20:25:37 GMTWWW-Authenticate: Basic realm="Users"

验证失败的时候,响应头加上WWW-Authenticate: Basic realm=”请求域”.
这种http 基本实现,几乎目前所有浏览器都支持.不过,大家可以发现,直接把用户名和密码只是进行一次base64 编码实际上是很不安全的,因为对base64进行反编码十分容易,所以这种验证虽然简便,但是很少会在公开访问的互联网使用,一般多用在小的私有系统,例如,你们家里头的路由器,多用这种认证方式.

Http 摘要认证###这个认证可以看做是基本认证的增强版本,使用随机数+密码进行md5,防止通过直接的分析密码MD5防止破解.摘要访问认证最初由 RFC 2069 (HTTP的一个扩展:摘要访问认证)中被定义加密步骤:

后来发现,就算这样还是不安全(md5 可以用彩虹表进行攻击),所以在RFC 2617入了一系列安全增强的选项;“保护质量”(qop)、随机数计数器由客户端增加、以及客户生成的随机数。这些增强为了防止如选择明文攻击的密码分析。

如果 qop 值为“auth”或未指定,那么 HA2 为

如果 qop 值为“auth-int”,那么 HA2 为
[图片上传中。。。(6)]

如果 qop 值为“auth”或“auth-int”,那么如下计算 response:
[图片上传中。。。(7)]

如果 qop 未指定,那么如下计算 response:

好了,知道加密步骤,下面我们用文字来描述一下;
最后,我们的response 由三步计算所得.
对用户名、认证域(realm)以及密码的合并值计算 MD5 哈希值,结果称为 HA1。
HA1 = MD5( “tom:Hi!:123456” )
= d8ae91c6c50fabdac442ef8d6a68ae8c

对HTTP方法以及URI的摘要的合并值计算 MD5 哈希值,例如,”GET” 和 “/index.html”,结果称为 HA2。
HA2 = MD5( “GET:/“ ) = 71998c64aea37ae77020c49c00f73fa8

最后生成的响应码
Response = MD5(“d8ae91c6c50fabdac442ef8d6a68ae8c:L4qfzASytyQJAC2B1Lvy2llPpj9R8Jd3:00000001:c2dc5b32ad69187a:auth:71998c64aea37ae77020c49c00f73fa8”) = 2f22e6d56dabb168702b8bb2d4e72453;

RFC2617 的安全增强的主要方式:
发起请求的时候,服务器会生成一个密码随机数(nonce)(而这个随机数只有每次”401”相应后才会更新),为了防止攻击者可以简单的使用同样的认证信息发起老的请求,于是,在后续的请求中就有一个随机数计数器(cnonce),而且每次请求必须必前一次使用的打.这样,服务器每次生成新的随机数都会记录下来,计数器增加.在RESPONSE 码中我们可以看出计数器的值会导致不同的值,这样就可以拒绝掉任何错误的请求.
请求样例(服务端 qop 设置为”auth”)
客户端 无认证
12

GET / HTTP/1.1Host: localhost

服务器响应(qop 为 ‘auth’)
123

HTTP/1.1 401 Authorization RequiredDate: Thu, 13 Jun 2013 20:25:37 GMTWWW-Authenticate: Digest realm="Hi!", nonce="HSfb5dy15hKejXAbZ2VXjVbgNC8sC1Gq", qop="auth"

客户端请求(用户名: “tom”, 密码 “123456”)
123456789

GET / HTTP/1.1Host: localhostAuthorization: Digest username="tom", realm="Hi!", nonce="L4qfzASytyQJAC2B1Lvy2llPpj9R8Jd3", uri="/", qop=auth, nc=00000001, cnonce="c2dc5b32ad69187a", response="2f22e6d56dabb168702b8bb2d4e72453"

服务端应答
1234

HTTP/1.1 200 OKDate: Thu, 13 Jun 2013 20:25:37 GMTContent-Type: application/json; charset=utf-8Content-Length: 53

注意qop 设置的时候慎用:auth-int,因为一些常用浏览器和服务端并没有实现这个协议.##前言##由于目前pomelo公开资料没有什么教程类的,所以就简单的写个学习笔记,用来记录一下。

通读api##个人认为,竟然要使用一个框架,对于框架提供的api必须要烂熟与心,pomelo的api 还是挺少的,所以量化一下,让初学者感觉读api不是那么可怕的事情。

7个大类###

Application (31 个方法)
由于这块的方法比较多,简单分一下类
环境
getBase();

set();

get

enabled();

disabled();

enbale();

disable();

configure();

初始化
start();

registerAdmin()

filter();

before()

after()

load()

loadConfig();

组件相关route

获取相关配置,组件方法getMaster()

getCurServer()

getServerId()

getServerType();

getServers();

getServersFromConfig();

getServerTypes();

getServerById();

getServerFromConfig();

getServersByType();

isFrontend()

isBackend()

isMaster()

addServers();

removerServers();

下面几个大类,方法比较少就不分类了。
ChannelService (5 个方法)
Channel (6 个方法)
LocalSessionService ( 4个方法)
LocalSession (6个方法)
SessionService (4个方法)
Pomelo(1个方法)

Pomelo : Hello world

安装好pomelo 要创建一个项目很简单:
pomelo init heloworld

ok,我们的一个helloworld 就这样完成了。

客户端编写###我们来看一下,客户端如何与服务端进行通信的打开web-server/public/index.html

阅读19-32

var pomelo = window.pomelo;
var host = "127.0.0.1"; 
var port = "3010";
function show() { 
   pomelo.init({ 
     host: host, 
     port: port, 
     log: true 
  }, function() { 
       pomelo.request("connector.entryHandler.entry","hellopomelo",function(data) { 
          alert(data.msg); 
       }); 
 });
}

从request请求connnecor.entryHandler.entry
我们在game-server目录app/servers/connector/handler/entryHandler.js
找到这么一个文件,打开这个文件以后我们发现了entry这个方法,现在我们能感叹,对于pomelo的通讯居然能够做到如此简单,为了验证我们的想法。我们在这个js文件里面加入

Handler.prototype.helloworld = function(msg, session, next){
    console.log(msg); 
    console.log(session); 
    next(null, {code: 200, msg: 'Hello world!'});
}

接着客户端修改:

pomelo.request("connector.entryHandler.helloworld", "hello pomelo", function(data) { 
       alert(data.msg);
   });
 });

运行项目,然后就能看到我们成功完成服务端与客户端的通讯了。
今天,我们简单的搞明白了pomelo 如何创建项目,然后,客户端如何发起请求,已经服务端如何编写能够接受客户端请求的方法。

你可能感兴趣的:(Pomelo 一)