NGINX userid 分析、解码
生成userid的代码在 http/modules/ngx_http_userid_filter_module.c 大概550行左右。
uid_set 是4个uint32构成的,其中比较有用的是第二个unit32,是userid的生成时间。第四个是一个递增值 以 0x03030302 为初始值,每次递增0x100。
default: /* AF_INET */
sin = (struct sockaddr_in *) c->local_sockaddr;
ctx->uid_set[0] = sin->sin_addr.s_addr;
break;
}
} else {
ctx->uid_set[0] = htonl(conf->service);
}
ctx->uid_set[1] = htonl((uint32_t) ngx_time());
ctx->uid_set[2] = htonl(start_value);
ctx->uid_set[3] = htonl(sequencer_v2);
sequencer_v2 += 0x100;
if (sequencer_v2 < 0x03030302) {
sequencer_v2 = 0x03030302;
}
// 用PHP解码nginx userid
$str = $_REQUEST["uid"] ?: $_COOKIE['uid'];
function nginx_userid_decode($str)
{
return unpack('N*', base64_decode(str_replace(' ', '+', $str)));
}
$hash = nginx_userid_decode($str);
var_dump($hash);
date_default_timezone_set("UTC");
var_dump(date("Y-m-d H:i:s", $hash[2]));
参考文章:
http://www.lsproc.com/blog/nginx_userid_decode/
[实践OK]Nginx 配置文件中处理Cookies的例子 nginx cookie
justwinit 2014-11-1 15:32
背景:在nginx用缓存插件时,个人博客如果在登录态时访问首页还是会缓存,自己登录后是用https管理,但是经常访问是http的,访问的是缓存的页面,自己不能得知自己是否已经登录上了的同时,也没法看自己的更多隐藏并置顶的博文,在这儿,发出能通过nginx处理Cookies实现是否读取缓存,当发现有这个cookie时,调用删除缓存接口删除掉同时跳转到后端https管理页面,进而解决了该问题。
————————————————————————————————————————————————————
1. 提取整个的Cookies内容到一个变量,然后可以在需要时引用,比如记录到日志里面,
if ( $http_cookie ~* "(.*)$") {
set $all_cookie $1;
}
变量$all_cookie就获得了cookie的值,可以用于运算了
2. 提取指定的一个cookie的值,然后根据需要使用,比如赋值给X-Real-Ip,
if ( $http_cookie ~* "pass_ip=(.+)(?:;|$)" ) {
set $one_cookie $1;
}
变量$one_cookie就获得了键值为pass_ip的这条cookie的值,可以用于运算了
3. 在proxy/fcgi等场景给Cookies增加内容,比如告诉后端你是那一台front。
proxy_set_header Cookie "$http_cookie; node_id=018"
- 文字
这里增加了名为node_id的一个cookie进去,当然,就这个例子来说,也可以这样传递前端的ID给backend:
proxy_set_header X-CDN-ID "018";
后端通过$_SERVER['HTTP_X_CDN_ID']就可以获取到赋值。
————————————————————————————————————————————————————————————————————————————
自己接合自己的情况实践了一下:
1. set $flag 0;
2. set $userid 0; #登录用户的id作为cookie值放cookie了。
3. ......
4. location ~ .*\.(php|php5)?$
5. { #实现Https访问博文及非主页面的列表下用Ctrl+F5删除前台用户访问的缓存文件
6. if ( $request_uri ~* "^/post/([0-9]+)/?([0-9]+)?/?([0-9]+)?/?$" ) #如URL转写后请求到博文及列表(不包括主页及后台管理功能)是条件1。
7. {
8. $flag "${flag}1";
9. }
10. if ($http_Cache_Control ~ "no-cache") #如果是上面博文连接且用了Ctrl+F5是条件2,实现删除生成的缓存文件,前端用户访问到最新更新博文页面。
11. {
12. $flag "${flag}1";
13. }
14. if ($flag = "011"){
15. $1 last;
16. }
17.
18. fastcgi_pass unix:/tmp/php-cgi.sock;
19. fastcgi_index index.php;
20. include fastcgi.conf;
21. }
delcache.php
1. <?php
2. //https://justwinit.cn/post/4082/
3. header("Content-type: text/html; charset=utf-8");
4. function purgeCache()
5. {
6. $cacheRoot = "/data/cache/ngx_fcgi_cache";
7. $url = "GET://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
8. if (emptyempty($_SERVER["HTTP_HOST"])||emptyempty($_SERVER["REQUEST_URI"])){
9. die('请输入正确的URL,检查Host参数入及URI参数是否正确。');
10. }
11. $md5 = md5($url);
12. $cacheFile = $cacheRoot . '/' . substr($md5, -1, 1) . '/' . substr($md5, -3, 2) . '/' . $md5;
13. //echo $url."<br>";
14. //echo $cacheFile."<br>";
15. if (!file_exists($cacheFile)) {
16. //echo ('缓存不存在。');
17. }
18. if (@unlink($cacheFile)) {
19. //echo '清除缓存成功。';
20. else {
21. //echo '清除缓存失败。';
22. }
23. //file_put_contents("/tmp/jack.txt",var_export($_SERVER,True) ,FILE_APPEND);
24. if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on"){//兼容访问时来自Https的情况:http访问时没有$_SERVER["HTTPS"]变量。
25. $url = "https://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
26. elseif(isset($_COOKIE['userpsw'])&&isset($_COOKIE['userid'])){//兼容是管理员登录后有Cookie时,访问转走Https,无缓存。
27. $url = "https://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
28. }
29. else{
30. $url = "http://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
31. }
32. flush();
33. ob_clean();
34. //header("location:".$url);//防止多次循环跳转,采用前端跳转。
35. echo "<meta http-equiv='refresh' content='0;url=$url' />";
36. exit;
37.
38. }
39. purgeCache()
40.
41. ?>