一、微信小程序
第一步:調用 wx.login獲取code 文檔地址
第二步:判斷用戶是否授權讀取用戶信息 文檔地址
第三步:調用wx.getUserInfo讀取用戶數據 文檔地址
第四步:由于小程序后臺授權域名無法授權微信的域名,所以我們只能通過我們自己的服務器去調用微信服務器去獲取用戶信息,故我們將wx.login獲取code 和 wx.getuserinfo 獲取的encrypteddata與iv 通過wx.request 請求傳入后臺
服務器返回的數據:
小程序代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
//調用登錄接口,獲取 code wx.login({ success: function (res) { wx.getsetting({ success(setres) { // 判斷是否已授權 if (!setres.authsetting[ 'scope.userinfo' ]) { // 授權訪問 wx.authorize({ scope: 'scope.userinfo' , success() { //獲取用戶信息 wx.getuserinfo({ lang: "zh_cn" , success: function (userres) { //發起網絡請求 wx.request({ url: config.loginwxurl, data: { code: res.code, encrypteddata: userres.encrypteddata, iv: userres.iv }, header: { "content-type" : "application/x-www-form-urlencoded" }, method: 'post' , //服務端的回掉 success: function (result) { var data = result.data.result; data.expiretime = nowdate + expiretime; wx.setstoragesync( "userinfo" , data); userinfo = data; } }) } }) } }) } else { //獲取用戶信息 wx.getuserinfo({ lang: "zh_cn" , success: function (userres) { //發起網絡請求 wx.request({ url: config.loginwxurl, data: { code: res.code, encrypteddata: userres.encrypteddata, iv: userres.iv }, header: { "content-type" : "application/x-www-form-urlencoded" }, method: 'post' , success: function (result) { var data = result.data.result; data.expiretime = nowdate + expiretime; wx.setstoragesync( "userinfo" , data); userinfo = data; } }) } }) } } }) } }) |
二、java服務端
根據code獲取openid與解碼用戶信息 代碼
所需要的jar包
1
2
3
4
5
6
7
8
9
10
|
<dependency> <groupid>org.codehaus.xfire</groupid> <artifactid>xfire-core</artifactid> <version> 1.2 . 6 </version> </dependency> <dependency> <groupid>org.bouncycastle</groupid> <artifactid>bcprov-jdk16</artifactid> <version> 1.46 </version> </dependency> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
/** * 微信小程序信息獲取 * * @author zhy */ public class wxappletuserinfo { private static logger log = logger.getlogger(wxappletuserinfo. class ); /** * 獲取微信小程序 session_key 和 openid * * @author zhy * @param code 調用微信登陸返回的code * @return */ public static jsonobject getsessionkeyoropenid(string code){ //微信端登錄code值 string wxcode = code; resourcebundle resource = resourcebundle.getbundle( "weixin" ); //讀取屬性文件 string requesturl = resource.getstring( "url" ); //請求地址 https://api.weixin.qq.com/sns/jscode2session map<string,string> requesturlparam = new hashmap<string,string>(); requesturlparam.put( "appid" , resource.getstring( "appid" )); //開發者設置中的appid requesturlparam.put( "secret" , resource.getstring( "appsecret" )); //開發者設置中的appsecret requesturlparam.put( "js_code" , wxcode); //小程序調用wx.login返回的code requesturlparam.put( "grant_type" , "authorization_code" ); //默認參數 //發送post請求讀取調用微信 https://api.weixin.qq.com/sns/jscode2session 接口獲取openid用戶唯一標識 jsonobject jsonobject = json.parseobject(urlutil.sendpost(requesturl, requesturlparam)); return jsonobject; } /** * 解密用戶敏感數據獲取用戶信息 * * @author zhy * @param sessionkey 數據進行加密簽名的密鑰 * @param encrypteddata 包括敏感數據在內的完整用戶信息的加密數據 * @param iv 加密算法的初始向量 * @return */ public static jsonobject getuserinfo(string encrypteddata,string sessionkey,string iv){ // 被加密的數據 byte [] databyte = base64.decode(encrypteddata); // 加密秘鑰 byte [] keybyte = base64.decode(sessionkey); // 偏移量 byte [] ivbyte = base64.decode(iv); try { // 如果密鑰不足16位,那么就補足. 這個if 中的內容很重要 int base = 16 ; if (keybyte.length % base != 0 ) { int groups = keybyte.length / base + (keybyte.length % base != 0 ? 1 : 0 ); byte [] temp = new byte [groups * base]; arrays.fill(temp, ( byte ) 0 ); system.arraycopy(keybyte, 0 , temp, 0 , keybyte.length); keybyte = temp; } // 初始化 security.addprovider( new bouncycastleprovider()); cipher cipher = cipher.getinstance( "aes/cbc/pkcs7padding" , "bc" ); secretkeyspec spec = new secretkeyspec(keybyte, "aes" ); algorithmparameters parameters = algorithmparameters.getinstance( "aes" ); parameters.init( new ivparameterspec(ivbyte)); cipher.init(cipher.decrypt_mode, spec, parameters); // 初始化 byte [] resultbyte = cipher.dofinal(databyte); if ( null != resultbyte && resultbyte.length > 0 ) { string result = new string(resultbyte, "utf-8" ); return json.parseobject(result); } } catch (nosuchalgorithmexception e) { log.error(e.getmessage(), e); } catch (nosuchpaddingexception e) { log.error(e.getmessage(), e); } catch (invalidparameterspecexception e) { log.error(e.getmessage(), e); } catch (illegalblocksizeexception e) { log.error(e.getmessage(), e); } catch (badpaddingexception e) { log.error(e.getmessage(), e); } catch (unsupportedencodingexception e) { log.error(e.getmessage(), e); } catch (invalidkeyexception e) { log.error(e.getmessage(), e); } catch (invalidalgorithmparameterexception e) { log.error(e.getmessage(), e); } catch (nosuchproviderexception e) { log.error(e.getmessage(), e); } return null ; } } |
發送請求的代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
/** * 向指定 url 發送post方法的請求 * * @param url 發送請求的 url * @param param 請求參數 * @return 所代表遠程資源的響應結果 */ ublic static string sendpost(string url, map<string, ?> parammap) { printwriter out = null ; bufferedreader in = null ; string result = "" ; string param = "" ; iterator<string> it = parammap.keyset().iterator(); while (it.hasnext()) { string key = it.next(); param += key + "=" + parammap.get(key) + "&" ; } try { url realurl = new url(url); // 打開和url之間的連接 urlconnection conn = realurl.openconnection(); // 設置通用的請求屬性 conn.setrequestproperty( "accept" , "*/*" ); conn.setrequestproperty( "connection" , "keep-alive" ); conn.setrequestproperty( "accept-charset" , "utf-8" ); conn.setrequestproperty( "user-agent" , "mozilla/4.0 (compatible; msie 6.0; windows nt 5.1;sv1)" ); // 發送post請求必須設置如下兩行 conn.setdooutput( true ); conn.setdoinput( true ); // 獲取urlconnection對象對應的輸出流 out = new printwriter(conn.getoutputstream()); // 發送請求參數 out.print(param); // flush輸出流的緩沖 out.flush(); // 定義bufferedreader輸入流來讀取url的響應 in = new bufferedreader( new inputstreamreader(conn.getinputstream(), "utf-8" )); string line; while ((line = in.readline()) != null ) { result += line; } } catch (exception e) { log.error(e.getmessage(), e); } //使用finally塊來關閉輸出流、輸入流 finally { try { if (out!= null ){ out.close(); } if (in!= null ){ in.close(); } } catch (ioexception ex){ ex.printstacktrace(); } } return result; } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blog.csdn.net/weilai_zhilu/article/details/77932630