2013-09-07 17:15:01
来 源
itjs.cn
Nginx
该篇讲述结合Nginx+Lua实现安全高并发的登录验证,希望对于初学Nginx服务器相关的朋友有帮助,更多Nginx安装、配置、报错处理等资源请本站内搜索。。

对于一个中型或大型网站,有n个子项目在不同的服务器甚至不同的IDC部署和运行,SSO(单点登录)和无SESSION已经是必备的功能。在这种情况下用户登陆后的身份验证就会是一个问题。一种简单的解决办法就是登陆时将用户的身份写入cookie,为了安全再写入一个cookie的校验,防止cookie篡改。

1 <?php

2 $secretkey = '1234567890abcdefghi';

3 // ……   取出数据到 $data 的代码略去

4 if( md5( sha1( $password ) ) == $data['passowrd'] ) { // 登陆成功

5     $_COOKIE['uid'] = 1234;

6     $_COOKIE['nickname'] = 'soga';

7     $_COOKIE['token'] = md5( "uid:1234&nickname:soga&secretkey:1234567890abcdefghi" );

8 }

9 ?>

验证登陆合法性:

01 <?php

02 $secretkey = '1234567890abcdefghi';

03

04 if( $_COOKIE['token'] == md5( "uid:{$_COOKIE['uid']}&nickname:{$_COOKIE['nickname']}&secretkey:{$secretkey}" ) ) {

05     $login = true;

06 }

07 else {

08     $login = false;

09 }

10 ?>

这样实现有一些问题存在,密钥$secretkey会暴露在所有的程序内,存在安全隐患。所有产品的程序中都需要内置token校验的算法。

如果能在webserver层进行校验,直接告诉应用层校验结果,就可以避免上面的问题。找一种webserver上安全、稳定、高性能的实现,并且开发成本低的方案。我选择的是Nginx + ngx_lua。Nginx的稳定性、高性能搭配Lua的高性能、低成本开发,简直绝配。

Nginx+ngx_lua的编译安装就不在这里讲了。

Nginx 配置:

1 access_by_lua_file '/dir/test.lua';

test.lua 代码:

01 local secretkey='1234567890abcdefghi'

02 if ngx.var.cookie_uid == nil or ngx.var.cookie_nickname == nil or ngx.var.cookie_token == nil then

03 ngx.req.set_header("Check-Login", "NULL")

04 return

05 end

06

07 local ctoken = ngx.md5('uid:' .. ngx.var.cookie_uid .. '&nickname:' .. ngx.var.cookie_nickname .. '&secretkey:' .. secretkey)

08

09 if ctoken == ngx.var.cookie_token then

10 ngx.req.set_header("Check-Login", "Yes")

11 else

12 ngx.req.set_header("Check-Login", "No")

13 end

14

15 return

然后就可以测试一下了:

无cookie登陆测试

01 [[email protected] soft]# curl -v "http://yuenshui.com:88/test.php"

02 * About to connect() to yuenshui.com port 88

03 *   Trying 122.0.66.162… connected

04 * Connected to yuenshui.com (122.0.66.162) port 88

05 > GET /test.php HTTP/1.1

06 > User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5

07 > Host: yuenshui.com:88

08 > Accept: */*

09 >

10 < HTTP/1.1 200 OK

11 < Server: nginx

12 < Date: Sun, 24 Jun 2012 10:38:09 GMT

13 < Content-Type: application/octet-stream

14 < Transfer-Encoding: chunked

15 < Connection: keep-alive

16 nil

17 <pre>$_SERVER:

18 Array

19 (

20     [TMP] => /tmp

21     [TMPDIR] => /tmp

22     [TEMP] => /tmp

23     [OSTYPE] =>

24     [MACHTYPE] =>

25     [MALLOC_CHECK_] => 2

26     [USER] => www

27     [HOME] => /home/www

28     [FCGI_ROLE] => RESPONDER

29     [SERVER_SOFTWARE] => nginx

30     [QUERY_STRING] =>

31     [REQUEST_METHOD] => GET

32     [CONTENT_TYPE] =>

33     [CONTENT_LENGTH] =>

34     [SCRIPT_NAME] => /test.php

35     [REQUEST_URI] => /test.php

36     [DOCUMENT_URI] => /test.php

37     [SERVER_PROTOCOL] => HTTP/1.1

38     [REMOTE_ADDR] => 114.93.76.130

39     [REMOTE_PORT] => 1037

40     [SERVER_ADDR] => 122.0.66.162

41     [SERVER_PORT] => 88

42     [SERVER_NAME] => yuenshui.com

43     [REDIRECT_STATUS] => 200

44     [HTTP_USER_AGENT] => curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5

45     [HTTP_HOST] => yuenshui.com:88

46     [HTTP_ACCEPT] => */*

47     [HTTP_CHECK_LOGIN] => NULL

48     [PHP_SELF] => /test.php

49     [REQUEST_TIME] => 1340534289

50     [argv] => Array

51         (

52         )

53

54     [argc] => 0

55 )

56

57 $_COOKIE:

58 Array

59 (

60 )

token错误的测试:

01 [[email protected] soft]# curl -b "uid=12345;nickname=soga;token=aa6f21ec0fcf008aa5250904985a817b"  "http://yuenshui.com:88/test.php"

02 <pre>$_SERVER:

03 Array

04 (

05     [TMP] => /tmp

06     [TMPDIR] => /tmp

07     [TEMP] => /tmp

08     [OSTYPE] =>

09     [MACHTYPE] =>

10     [MALLOC_CHECK_] => 2

11     [USER] => www

12     [HOME] => /home/www

13     [FCGI_ROLE] => RESPONDER

14     [SERVER_SOFTWARE] => nginx

15     [QUERY_STRING] =>

16     [REQUEST_METHOD] => GET

17     [CONTENT_TYPE] =>

18     [CONTENT_LENGTH] =>

19     [SCRIPT_NAME] => /test.php

20     [REQUEST_URI] => /test.php

21     [DOCUMENT_URI] => /test.php

22     [SERVER_PROTOCOL] => HTTP/1.1

23     [REMOTE_ADDR] => 114.93.76.130

24     [REMOTE_PORT] => 1059

25     [SERVER_ADDR] => 122.0.66.162

26     [SERVER_PORT] => 88

27     [SERVER_NAME] => yuenshui.com

28     [REDIRECT_STATUS] => 200

29     [HTTP_USER_AGENT] => curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5

30     [HTTP_HOST] => yuenshui.com:88

31     [HTTP_ACCEPT] => */*

32     [HTTP_COOKIE] => uid=12345;nickname=soga;token=aa6f21ec0fcf008aa5250904985a817b

33     [HTTP_CHECK_LOGIN] => No

34     [PHP_SELF] => /test.php

35     [REQUEST_TIME] => 1340537366

36     [argv] => Array

37         (

38         )

39

40     [argc] => 0

41 )

42

43 $_COOKIE:

44 Array

45 (

46     [uid] => 12345

47     [nickname] => soga

48     [token] => aa6f21ec0fcf008aa5250904985a817b

49 )

token正确的测试:

01 [[email protected] soft]# curl -b "uid=1234;nickname=soga;token=aa6f21ec0fcf008aa5250904985a817b"  "http://yuenshui.com:88/test.php"

02 <pre>$_SERVER:

03 Array

04 (

05     [TMP] => /tmp

06     [TMPDIR] => /tmp

07     [TEMP] => /tmp

08     [OSTYPE] =>

09     [MACHTYPE] =>

10     [MALLOC_CHECK_] => 2

11     [USER] => www

12     [HOME] => /home/www

13     [FCGI_ROLE] => RESPONDER

14     [SERVER_SOFTWARE] => nginx

15     [QUERY_STRING] =>

16     [REQUEST_METHOD] => GET

17     [CONTENT_TYPE] =>

18     [CONTENT_LENGTH] =>

19     [SCRIPT_NAME] => /test.php

20     [REQUEST_URI] => /test.php

21     [DOCUMENT_URI] => /test.php

22     [SERVER_PROTOCOL] => HTTP/1.1

23     [REMOTE_ADDR] => 114.93.76.130

24     [REMOTE_PORT] => 1059

25     [SERVER_ADDR] => 122.0.66.162

26     [SERVER_PORT] => 88

27     [SERVER_NAME] => yuenshui.com

28     [REDIRECT_STATUS] => 200

29     [HTTP_USER_AGENT] => curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5

30     [HTTP_HOST] => yuenshui.com:88

31     [HTTP_ACCEPT] => */*

32     [HTTP_COOKIE] => uid=1234;nickname=soga;token=aa6f21ec0fcf008aa5250904985a817b

33     [HTTP_CHECK_LOGIN] => Yes

34     [PHP_SELF] => /test.php

35     [REQUEST_TIME] => 1340537463

36     [argv] => Array

37         (

38         )

39

40     [argc] => 0

41 )

42

43 $_COOKIE:

44 Array

45 (

46     [uid] => 12345

47     [nickname] => soga

48     [token] => aa6f21ec0fcf008aa5250904985a817b

49 )

http://yuenshui.com:88/test.php   打印信息的PHP代码:

01 <pre><?php

02 echo "$_SERVER:rn";

03 unset($_SERVER['SCRIPT_FILENAME']);

04 unset($_SERVER['DOCUMENT_ROOT']);

05 unset($_SERVER['PATH']);

06 unset($_SERVER['HOSTNAME']);

07 unset($_SERVER['GATEWAY_INTERFACE']);

08 print_r($_SERVER);

09 echo "rn$_COOKIE:rn";

10 print_r($_COOKIE);

11 ?>

声明: 此文观点不代表本站立场;转载须要保留原文链接;版权疑问请联系我们。