对于一个中型或大型网站,有n个子项目在不同的服务器甚至不同的IDC部署和运行,SSO(单点登录)和无SESSION已经是必备的功能。在这种情况下用户登陆后的身份验证就会是一个问题。一种简单的解决办法就是登陆时将用户的身份写入cookie,为了安全再写入一个cookie的校验,防止cookie篡改。
验证登陆合法性:
这样实现有一些问题存在,密钥$secretkey会暴露在所有的程序内,存在安全隐患。所有产品的程序中都需要内置token校验的算法。
如果能在webserver层进行校验,直接告诉应用层校验结果,就可以避免上面的问题。找一种webserver上安全、稳定、高性能的实现,并且开发成本低的方案。我选择的是Nginx + ngx_lua。Nginx的稳定性、高性能搭配Lua的高性能、低成本开发,简直绝配。
Nginx+ngx_lua的编译安装就不在这里讲了。
Nginx 配置:
test.lua 代码:
然后就可以测试一下了:
无cookie登陆测试
$ _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 ( x 86 _ 64 - redhat - linux - gnu) libcurl / 7 . 15 . 5 OpenSSL / 0 . 9 . 8 b 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错误的测试:
$ _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 ( x 86 _ 64 - redhat - linux - gnu) libcurl / 7 . 15 . 5 OpenSSL / 0 . 9 . 8 b 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 = aa 6 f 21 ec 0 fcf 008 aa 5250904985 a 817b
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正确的测试:
$ _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 ( x 86 _ 64 - redhat - linux - gnu) libcurl / 7 . 15 . 5 OpenSSL / 0 . 9 . 8 b 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 = aa 6 f 21 ec 0 fcf 008 aa 5250904985 a 817b
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代码:
上面是所有的测试程序。大家也可以通过curl进行测试http://yuenshui.com:88/test.php