第一步:熟悉Nginx的ngx_http_auth_request_module模块,具体见官网:http://nginx.org/en/docs/http/ngx_http_auth_request_module.html;
第二步:Nginx需要引入ngx_http_auth_request_module模块,然后配置conf文件,具体配置如下:
第三步(1):配置完之后,先完成前端,将用户名和密码base64之后,以?坠在接口后面,类似于Get发送数据的那样,发送给后台。
第三步(2):配置完之后,先完成前端,将用户名和密码base64之后,放在RequestHeader里面发送给后台。
我的主要思路如下(卢老师的思路与指导):
第四步:编写auth接口,费了老大劲,我真的是不会c语言,经过这一次,更加不喜欢;
两种方法:
第一种,对应第三步(1):用cgi的环境变量去获取前端发送的base64之后的用户名和密码,然后和从设备中获取到的用户名密码,进行比对,如果相同则返回200,继续执行请求的接口;如果返回401,则报错/或者load登录页面;
第二种,对应第三步(2):用fastcgi内置的FCGX_GetParam函数去获取对应的RequsetHeader里面的base64之后的用户名和密码,后面的操作和第一种的一样;
// 具体步骤如下:
// 第一种:
// 首先获取接口的字符串
queryString = getenv("QUERY_STRING");
// 然后判断是否为空
if (queryString != NULL) {
//如果不为空,则 获取Authorization
//memset函数是为了清空字符数组,以免累加出错
memset(Authorization, 0, 60);
//sscanf函数截取字符串,但是这个函数有一个缺点就是遇到空格就会终止,有可能报错,所 以用户名和密码的限定需要前端做好
sscanf(queryString, "Authorization=%s", Authorization);
// 调用共享变量
app_en_men();
// 获取后台已经有的用户名和密码
memset(username, 0, 20);
memset(psw, 0, 20);
strcpy(username, shared_sys_param_w->loginID);
strcpy(psw, shared_sys_param_w->loginpasswd);
// 拼接字符串
memset(user, 0, 60);
strcat(user, username);
strcat(user, ":");
strcat(user, psw);
// 由于拼接后的字符串可能存在空格,空格在编码成base64的时候也当作一个有效字符,为了避免出错,删除字符串的空格
// 删除拼接后的字符串里的空格
delSpace(user);
// 比较一下,如果相同,则说明返回200,正常登录
if (strcmp(Authorization, base64_encode(user)) == 0) {
printf("Status: 200 Ok\nContent-type: text/plain\n\n");
continue;
}
}
// 如果为空或者不相同,则返回401,重新登录
printf("Status: 401 Unauthorized\nContent-type: text/plain\n\n");
// PS:这种方式有一个缺点,直接去访问/auth接口的时候是没有问题的,但是由于有很多页面,刚开始去请求数据的时候都需要去验证当前页面是否已经登录,这就需要将用户名和密码坠到当前去请求的这个接口,比如/upload_cgi?auth=xxx这样,一运行页面,cgi直接挂掉,我也没找出为什么,希望有高人可以分享;
// 第二种:
// 为了后面用到的一些变量,提前声明
// for FCGX_Accept
FCGX_Stream *in, *out, *err;
FCGX_ParamArray envp;
// fastcgi必须的步骤
while (FCGX_Accept(&in, &out, &err, &envp) >= 0) {
// 获取头信息里面的认证信息,用这个函数需哟啊注意的是,第一个参数必须是HTTP_xxx,而且第二个参数必须用FCGX_ParamArray来声明
b64_auth = FCGX_GetParam("HTTP_AUTHORIZATION", envp);
// 获取到的数据不为空
if (b64_auth != NULL) {
// 其中的操作和第一种一样,这里不再赘述
}
//获取到的数据为空或者是和设备端的数据不匹配,返回401
FCGX_FPrintF(out, "Status: 401 Unauthorized\nContent-type: text/plain\n\n");
FCGX_PutS("error: no auth or wrong.\n", out);
}
// PS:这一种是我现在用的,目前乜有发现存在的BUG,如有高人发现,请指教哦
//最后:谢谢一直陪在我身后的超级牛掰的卢老师https://my.oschina.net/lpe234, 在他的帮助下,我一直在进步!