微信電腦網頁二維碼掃描登錄簡單實現


補充:

  從后台看到,好像很多非技術人員從搜索引擎收到本博客,好像目的是因為不知道網頁版的微信登錄地址。這里提供一下。

 

  https://wx.qq.com/   點擊鏈接,用手機微信掃描一下就可以登錄了。

 

正文:

  看那個微信電腦端的掃描登錄看起來叼叼噠,找了一篇文章了解一下具體的實現思路和過程,看了牛人的分析后,發現實現起來也不是很難,這里我就簡單的實現了一下。可能功能和流暢度沒有微信做的好,具體是我對前端不是很了解。

  好了,不多說,首先要有一個二維碼的生成軟件才行,這里找了一個叫QrenCode的軟件,好處是可以在命令行中進行生成。(下載地址: http://pkgs.org/download/qrencode 找自己合適的下載 應該還要一個依賴庫libqrencode)

1 #QrenCode 下面是centos6.4的安裝命令 
2 wget http://dl.fedoraproject.org/pub/epel/6/i386/qrencode-3.4.2-1.el6.i686.rpm
3 wget http://ftp.altlinux.org/pub/distributions/ALTLinux/Sisyphus/i586/RPMS.classic/libqrencode-3.4.3-alt1.i586.rpm 
4 rpm -ivh libqrencode-3.4.3-alt1.i586.rpm
5 rpm -ivh qrencode-3.4.2-1.el6.i686.rpm

  命令行生成二維碼的方法

生成二維碼格式
qrencode -o [filename.png] ‘[text/url/information to encode]‘
參數
-o 表示生成到指定文件
-s num 表示生成的二維碼的大小,每個點使用num個像素代替
-v num 表示生成的版本

  創建一個login.c文件用於創建一個用於顯示二維碼的cgi (這里用的服務器是我博客中提到的web服務器,雖然還有bug,但是還是夠用的。其他的服務器應該也是可以的。用自己的服務器會不會被罵((逃 )

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 #include <time.h>
 5 #include <unistd.h>
 6 #include <sys/wait.h>
 7 
 8 int rand_str(char *str,int num)
 9 {
10     int i,j;
11     for(i=0;i<num;i++)
12     {
13         j=rand()%3;
14         if(j==0)
15         {
16             str[i]='a'+rand()%26;
17         }
18         else if(j==1)
19         {
20             str[i]='A'+rand()%26;
21         }
22         else if(j==2)
23         {
24             str[i]='0'+rand()%10;
25         }
26     }
27     str[i]=0;
28     return 0;
29 }
30 
31 int main(int argc,char **args)
32 {
33     int i;
34     char code[64];
35     char str[64];
36     char qc[128];
37     char filename[64];
38     char cmd[128];
39     int status;
40     pid_t pid;
41     srand(time(NULL));
42     rand_str(code,20);
43 
44 
45     strcpy(qc,"http://192.168.198.157:8080/login/");
46     strcat(qc,code);
47 
48     strcpy(filename,code);
49     strcat(filename,".png");
50 
51     sprintf(cmd,"qrencode -o www/qc/%s -s 10 '%s'",filename,qc);
52 
53     //生成二維碼
54     system(cmd);
55 
56     printf("<html><head><title>掃描登錄</title></head><body>");
57     printf("<img src=\"%s\" />",filename);
58     printf("</body></html>");
59 
60     return 0;
61 }

  運行結果,基本每次都是可以隨機的。

  這里還有一點要說的,就是隨機算法的問題(好像是什么十大算法之類的),我弄不了,使用的是庫函數。我這個程序的隨機種子是1秒一次,也就是1秒才會變換一次,還有一個問題就是這個srand函數的隨機種子數好像不多,應該是6W多吧,這個如果用戶一多就麻煩了。我這里想到的另一個辦法是根據那個毫秒數來弄(例如用加密算法來對這個毫秒進行加密得到一個字符串,再加個什么的都可以,例如用戶名什么的,最主要的是保證唯一,這個如果實際產品中實現應該不是很難)。

  接下來要做的是根據這個url地址再生成一個cgi程序,用於手機APP的調用。我這里想到的辦法是每次刷新這個login頁面時,就復制一個cgi程序,給APP調用。APP的調用機制是根據這個用二維碼生成的url地址發送一個確認包。(確認包使用get方式可以,用post方式也可以,另外用一台服務器也是可以的,這個要看用戶量等具體情況。總之就是這樣了。)

  我這里為了演示的方便就采用get方式(原因嘛?我沒有APP這種客戶端,就簡單的在手機上對這個url后面加上個參數了。)

  本次實驗用到的3個程序代碼 (代碼中的目錄問題是因為我的服務器設計有缺陷,導致有些目錄要使用相對於程序的絕對路徑,有的可以使用相對路徑,總之我試驗的時候有點坑,不過不影響代碼的可讀性)

  login.c

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 #include <time.h>
 5 #include <unistd.h>
 6 #include <sys/wait.h>
 7 
 8 int rand_str(char *str,int num)
 9 {
10     int i,j;
11     for(i=0;i<num;i++)
12     {
13         j=rand()%3;
14         if(j==0)
15         {
16             str[i]='a'+rand()%26;
17         }
18         else if(j==1)
19         {
20             str[i]='A'+rand()%26;
21         }
22         else if(j==2)
23         {
24             str[i]='0'+rand()%10;
25         }
26     }
27     str[i]=0;
28     return 0;
29 }
30 
31 int main(int argc,char **args)
32 {
33     int i;
34     char code[64];
35     char str[64];
36     char qc[128];
37     char filename[64];
38     char cmd[128];
39     int status;
40     pid_t pid;
41     srand(time(NULL));
42     rand_str(code,20);
43 
44 
45     strcpy(qc,"http://192.168.198.157:8080/qc/");
46     strcat(qc,code);
47 
48     strcpy(filename,code);
49     strcat(filename,".png");
50 
51     //生成二維碼
52     sprintf(cmd,"qrencode -o www/qc/%s -s 10 '%s'",filename,qc);
53     system(cmd);
54 
55 
56     printf("<html><head><title>掃描登錄</title></head><body>");
57     printf("<img src=\"%s\" />",filename);
58     printf("<br>如果APP上顯示登錄成功那么就點擊該按鈕進行跳轉<br>");
59     printf("<form method=\"get\" action=\"welcome\">");//這里的action居然不能帶參數,哎前端不會啊
60     printf("<input type=\"hidden\" name=\"code\" value=\"%s\">",code);
61     printf("<input type=\"submit\" value=\"提交\"></form>");
62     printf("</body></html>");
63 
64     sprintf(cmd,"ln -s callback www/qc/%s",code);
65     system(cmd);
66 
67     return 0;
68 }

  callback.c

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 
 5 int split(char **arr,char *str,const char*del)
 6 {
 7     char *s=NULL;
 8     int i=0;
 9     s=strtok(str,del);
10     while(s!=NULL)
11     {
12         *arr++=s;
13         s=strtok(NULL,del);
14         i++;
15     }
16     return i;
17 }
18 
19 void split_key(char *ch,char *key,char *value)
20 {
21     int len;
22     int i;
23     int j;
24     len=strlen(ch);
25     j=0;
26     for(i=0;i<len;i++)
27     {
28         if(ch[i]=='=')
29         {
30             i++;
31             break;
32         }
33         key[j]=ch[i];
34         j++;
35     }
36     key[j]=0;
37     j=0;
38     for(;i<len;i++)
39     {
40         value[j]=ch[i];
41         j++;
42     }
43     value[j]=0;
44     return ;
45 }
46 
47 int main(int argc,char **args)
48 {
49     char *data;
50     char *myargs[32];
51     int cnt=0;
52     int i;
53     char key[32],value[32];
54     char username[32],code[32];
55     char cmd[128];
56     FILE * fp=NULL;
57     memset(myargs,0,sizeof(myargs));
58     memset(username,0,sizeof(username));
59     cnt=split(myargs,args[1],"&");
60 
61     for(i=0;i<cnt;i++)
62     {
63         split_key(myargs[i],key,value);
64         if(strcmp(key,"username")==0)
65             strcpy(username,value);
66         if(strcmp(key,"code")==0)
67             strcpy(code,value);
68     }
69 
70     //這里可以寫上完整的網頁和處理過程
71 
72     if(username[0]!=0)
73     {
74         printf("<p>通過移動端進行用戶登錄成功,當前登陸的用戶是:</p>");
75         printf("<font color=\"red\">%s</font>   現在可以在瀏覽器中進行操作了",username);
76     }
77     else
78     {
79         printf("參數錯誤\n");
80     }
81 
82     sprintf(cmd,"www/qc/%s.html",code);
83     fp=fopen(cmd,"w");
84     fprintf(fp,"您好,用戶:%s  通過APP移動端登錄成功.  采用的uuid是:%s\n",username,code);
85     fclose(fp);
86 
87     return 0;
88 }

  welcome.c

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <unistd.h>
 5 
 6 int split(char **arr,char *str,const char*del)
 7 {
 8     char *s=NULL;
 9     int i=0;
10     s=strtok(str,del);
11     while(s!=NULL)
12     {
13         *arr++=s;
14         s=strtok(NULL,del);
15         i++;
16     }
17     return i;
18 }
19 
20 void split_key(char *ch,char *key,char *value)
21 {
22     int len;
23     int i;
24     int j;
25     len=strlen(ch);
26     j=0;
27     for(i=0;i<len;i++)
28     {
29         if(ch[i]=='=')
30         {
31             i++;
32             break;
33         }
34         key[j]=ch[i];
35         j++;
36     }
37     key[j]=0;
38     j=0;
39     for(;i<len;i++)
40     {
41         value[j]=ch[i];
42         j++;
43     }
44     value[j]=0;
45     return ;
46 }
47 
48 int main(int argc,char **args)
49 {
50     char *data;
51     char *myargs[32];
52     int cnt=0;
53     int i;
54     char key[32],value[32];
55     char code[32];
56     char cmd[128];
57     memset(myargs,0,sizeof(myargs));
58     cnt=split(myargs,args[1],"&");
59 
60     for(i=0;i<cnt;i++)
61     {
62         split_key(myargs[i],key,value);
63         if(strcmp(key,"code")==0)
64             strcpy(code,value);
65     }
66 
67     sprintf(cmd,"www/qc/%s.html",code);
68     //這里可以寫上完整的網頁
69     if(access(cmd,F_OK)==0)
70     {
71         printf("終於登錄了,可以各種操作了");
72     }
73     else
74     {
75         printf("請確認是否通過APP掃描登陸過");
76     }
77 
78     return 0;
79 }

  代碼就放在那里,具體的操作過程就用截圖方式進行講解

  (1) 打開服務器,輸入網址: http://192.168.198.157:8080/qc/login

  (2)如果沒有通過移動端的的驗證,此時點擊提交是不起作用的。

  (3)我們使用手機客戶端進行驗證(由於我沒有設計可用的APP,這里使用GET方式,自己構造一個。注意,如果已經有了客戶端那么,可以通過客戶端APP自行構造一個請求,可以是post,也可以是另外一個action然后進行驗證什么的。總之怎么安全,怎么方便怎么來。)下面這個是我手機通過掃二維碼,然后手動構造一個get請求得到的。(請求如下: http://192.168.198.157:8080/qc/GL199v8zsHV2bu7R7Qad?username=admin&code=GL199v8zsHV2bu7R7Qad)

  (4)好了,我們可以在那個login界面上點擊登錄就可以登錄進去了。(這里為什么不像微信那樣,APP客戶端一掃描確認,瀏覽器就直接跳轉,而是要手動點擊提交按鈕呢?那是因為我對前端的技術不是很了解,不知道怎么構建一個長連接,和跳轉什么的。所以就弄成簡單的,手動點擊了,不過這些都不是重點)

  (5)下面這些是服務器的一些信息

  還有一個問題就是如果訪問的次數多了,那些中間文件就太多了,這時可以通過一個腳本,按時間進行清理。

  處理的流程圖

  終於完成了。心情有點小激動了。

 

  參考資料: http://www.linuxeden.com/html/softuse/20110328/108018.html

        http://www.zhihu.com/question/20368066 (技術原理來源)

  本文地址: http://www.cnblogs.com/wunaozai/p/3947635.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM