微信網頁授權—驗證伺服器配置
第一步,成為開發者
1.填寫伺服器配置
登入微信公眾平臺官網後,在公眾平臺官網的開發-基本設定頁面,勾選協議成為開發者,點選“修改配置”按鈕,填寫伺服器地址(URL)、Token和EncodingAESKey,其中URL是開發者用來接收微信訊息和事件的介面URL。Token可由開發者可以任意填寫,用作生成簽名(該Token會和介面URL中包含的Token進行比對,從而驗證安全性)。EncodingAESKey由開發者手動填寫或隨機生成,將用作訊息體加解密金鑰。
Url伺服器地址是微信回撥地址,必須以 http://或https://開頭,埠號必須為80或443。
Token令牌由使用者自己定義,數字或字母,長度為3~32字元。
EncodingAESKey隨機生成即可。
加密方式可以選明文模式和安全模式。
2.驗證伺服器配置
點選啟用後,微信伺服器將傳送GET請求到你的伺服器地址URL上,並攜帶四個引數:signature 微信加密簽名(signature結合了開發者填寫的token引數和請求中的timestamp引數、nonce引數),timestamp 時間戳,nonce 隨機數,echostr 隨機字串。
伺服器需要接受上面四個引數,並進行校驗,若確認此次GET請求來自微信伺服器,請原樣返回echostr引數內容,則接入生效,成為開發者成功,否則接入失敗。
校驗流程為:
1)將token、timestamp、nonce三個引數進行字典序排序
2)將三個引數字串拼接成一個字串進行sha1加密
3)開發者獲得加密後的字串可與signature對比,標識該請求來源於微信
校驗程式碼(java)
package com.sh.inter;
import java.io.IOException;
import java.util.Arrays;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sh.util.SHA1;
/**
* 開發者通過檢驗signature對請求進行校驗(下面有校驗方式)。若確認此次GET請求來自微信伺服器,請原樣返回echostr引數內容,則接入生效,成為開發者成功,否則接入失敗。
* 加密/校驗流程如下:
* 1)將token、timestamp、nonce三個引數進行字典序排序
* 2)將三個引數字串拼接成一個字串進行sha1加密
* 3)開發者獲得加密後的字串可與signature對比,標識該請求來源於微信
* @author 季小沫的故事
*/
public class AccessWet extends HttpServlet {
private static final long serialVersionUID = 1L;
//使用者自定義TOKEN
public static String TOKEN = "micomo";//使用者在微信伺服器配置填寫的token
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 微信加密簽名
String signature = request.getParameter("signature");
// 隨機字串
String echostr = request.getParameter("echostr");
// 時間戳
String timestamp = request.getParameter("timestamp");
// 隨機數
String nonce = request.getParameter("nonce");
// 字典序排序
String[] str = { TOKEN, timestamp, nonce };
Arrays.sort(str);
String bigStr = str[0] + str[1] + str[2];
// SHA1加密
String digest = new SHA1().getDigestOfString(bigStr.getBytes()).toLowerCase();
// 確認請求來至微信
if (digest.equals(signature)) {
response.getWriter().append(echostr);
}
}
}
SHA1加密程式碼
package com.sh.util;
/**
*
* 檔名 : WechatCallbackApi.java<br/>
* 作者 : songhuihui <br/>
* 建立日期 : 2013-9-27<br/>
* 站點 : http://wuzhut.com<br/>
*/
public class SHA1 {
private final int[] abcde = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 };
// 摘要資料儲存陣列
private int[] digestInt = new int[5];
// 計算過程中的臨時資料儲存陣列
private int[] tmpData = new int[80];
// 計算sha-1摘要
private int process_input_bytes(byte[] bytedata) {
// 初試化常量
System.arraycopy(abcde, 0, digestInt, 0, abcde.length);
// 格式化輸入位元組陣列,補10及長度資料
byte[] newbyte = byteArrayFormatData(bytedata);
// 獲取資料摘要計算的資料單元個數
int MCount = newbyte.length / 64;
// 迴圈對每個資料單元進行摘要計算
for (int pos = 0; pos < MCount; pos++) {
// 將每個單元的資料轉換成16個整型資料,並儲存到tmpData的前16個數組元素中
for (int j = 0; j < 16; j++) {
tmpData[j] = byteArrayToInt(newbyte, (pos * 64) + (j * 4));
}
// 摘要計算函式
encrypt();
}
return 20;
}
// 格式化輸入位元組陣列格式
private byte[] byteArrayFormatData(byte[] bytedata) {
// 補0數量
int zeros = 0;
// 補位後總位數
int size = 0;
// 原始資料長度
int n = bytedata.length;
// 模64後的剩餘位數
int m = n % 64;
// 計算新增0的個數以及新增10後的總長度
if (m < 56) {
zeros = 55 - m;
size = n - m + 64;
} else if (m == 56) {
zeros = 63;
size = n + 8 + 64;
} else {
zeros = 63 - m + 56;
size = (n + 64) - m + 64;
}
// 補位後生成的新陣列內容
byte[] newbyte = new byte[size];
// 複製陣列的前面部分
System.arraycopy(bytedata, 0, newbyte, 0, n);
// 獲得陣列Append資料元素的位置
int l = n;
// 補1操作
newbyte[l++] = (byte) 0x80;
// 補0操作
for (int i = 0; i < zeros; i++) {
newbyte[l++] = (byte) 0x00;
}
// 計算資料長度,補資料長度位共8位元組,長整型
long N = (long) n * 8;
byte h8 = (byte) (N & 0xFF);
byte h7 = (byte) ((N >> 8) & 0xFF);
byte h6 = (byte) ((N >> 16) & 0xFF);
byte h5 = (byte) ((N >> 24) & 0xFF);
byte h4 = (byte) ((N >> 32) & 0xFF);
byte h3 = (byte) ((N >> 40) & 0xFF);
byte h2 = (byte) ((N >> 48) & 0xFF);
byte h1 = (byte) (N >> 56);
newbyte[l++] = h1;
newbyte[l++] = h2;
newbyte[l++] = h3;
newbyte[l++] = h4;
newbyte[l++] = h5;
newbyte[l++] = h6;
newbyte[l++] = h7;
newbyte[l++] = h8;
return newbyte;
}
private int f1(int x, int y, int z) {
return (x & y) | (~x & z);
}
private int f2(int x, int y, int z) {
return x ^ y ^ z;
}
private int f3(int x, int y, int z) {
return (x & y) | (x & z) | (y & z);
}
private int f4(int x, int y) {
return (x << y) | x >>> (32 - y);
}
// 單元摘要計算函式
private void encrypt() {
for (int i = 16; i <= 79; i++) {
tmpData[i] = f4(tmpData[i - 3] ^ tmpData[i - 8] ^ tmpData[i - 14]
^ tmpData[i - 16], 1);
}
int[] tmpabcde = new int[5];
for (int i1 = 0; i1 < tmpabcde.length; i1++) {
tmpabcde[i1] = digestInt[i1];
}
for (int j = 0; j <= 19; j++) {
int tmp = f4(tmpabcde[0], 5)
+ f1(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4]
+ tmpData[j] + 0x5a827999;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int k = 20; k <= 39; k++) {
int tmp = f4(tmpabcde[0], 5)
+ f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4]
+ tmpData[k] + 0x6ed9eba1;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int l = 40; l <= 59; l++) {
int tmp = f4(tmpabcde[0], 5)
+ f3(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4]
+ tmpData[l] + 0x8f1bbcdc;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int m = 60; m <= 79; m++) {
int tmp = f4(tmpabcde[0], 5)
+ f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4]
+ tmpData[m] + 0xca62c1d6;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int i2 = 0; i2 < tmpabcde.length; i2++) {
digestInt[i2] = digestInt[i2] + tmpabcde[i2];
}
for (int n = 0; n < tmpData.length; n++) {
tmpData[n] = 0;
}
}
// 4位元組陣列轉換為整數
private int byteArrayToInt(byte[] bytedata, int i) {
return ((bytedata[i] & 0xff) << 24) | ((bytedata[i + 1] & 0xff) << 16)
| ((bytedata[i + 2] & 0xff) << 8) | (bytedata[i + 3] & 0xff);
}
// 整數轉換為4位元組陣列
private void intToByteArray(int intValue, byte[] byteData, int i) {
byteData[i] = (byte) (intValue >>> 24);
byteData[i + 1] = (byte) (intValue >>> 16);
byteData[i + 2] = (byte) (intValue >>> 8);
byteData[i + 3] = (byte) intValue;
}
// 將位元組轉換為十六進位制字串
private static String byteToHexString(byte ib) {
char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
'B', 'C', 'D', 'E', 'F' };
char[] ob = new char[2];
ob[0] = Digit[(ib >>> 4) & 0X0F];
ob[1] = Digit[ib & 0X0F];
String s = new String(ob);
return s;
}
// 將位元組陣列轉換為十六進位制字串
private static String byteArrayToHexString(byte[] bytearray) {
String strDigest = "";
for (int i = 0; i < bytearray.length; i++) {
strDigest += byteToHexString(bytearray[i]);
}
return strDigest;
}
// 計算sha-1摘要,返回相應的位元組陣列
public byte[] getDigestOfBytes(byte[] byteData) {
process_input_bytes(byteData);
byte[] digest = new byte[20];
for (int i = 0; i < digestInt.length; i++) {
intToByteArray(digestInt[i], digest, i * 4);
}
return digest;
}
// 計算sha-1摘要,返回相應的十六進位制字串
public String getDigestOfString(byte[] byteData) {
return byteArrayToHexString(getDigestOfBytes(byteData));
}
public static void main(String[] args) {
String data = "123456";
System.out.println(data);
String digest = new SHA1().getDigestOfString(data.getBytes());
System.out.println(digest);
// System.out.println( ToMD5.convertSHA1(data).toUpperCase());
}
}
精簡版SHA1類
package com.sh.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class SHA1 {
public static String sha1(String input) throws NoSuchAlgorithmException {
MessageDigest mDigest = MessageDigest.getInstance("SHA1");
byte[] result = mDigest.digest(input.getBytes());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < result.length; i++) {
sb.append(Integer.toString((result[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
}
}
到此,完成伺服器配置,並且成功驗證,成為開發者。
根據相關義務需求,呼叫微信開放介面。
相關微信開發文件
相關推薦
微信網頁授權—驗證伺服器配置
第一步,成為開發者 1.填寫伺服器配置 登入微信公眾平臺官網後,在公眾平臺官網的開發-基本設定頁面,勾選協議成為開發者,點選“修改配置”按鈕,填寫伺服器地址(URL)、Token和EncodingAESKey,其中URL是開發者用來接收微信訊息和事件的介面U
微信伺服器配置的一點點經驗(內含:驗證伺服器出現token驗證失敗的處理,接收事件出現XML格式錯誤,微信網頁授權獲取 access token 報錯40125)
首先需要多些網上的大神 連結:https://bbs.csdn.net/topics/390991193 ; https://blog.csdn.net/sinat_22878395/article/details/69258165 ; https://blog.csdn.net/hangh
微信網頁授權獲取用戶信息等機制
json 開發者 userinfo 技術分享 nal amp 分隔 response unionid 參考官方文檔 https://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html 1.用戶進入授權
微信網頁授權-公眾號支付(獲取openid、用戶信息等)
blog red code rect ref true 說明 oauth2 具體細節 名詞解釋: openid 用戶唯一標識,請註意,在未關註公眾號時,用戶訪問公眾號的網頁,也會產生一個用戶和公眾號唯一的OpenID 業務功能描述:實現H
微信網頁授權
cde 註意 connect encode res str abc 有關 href 有關微信網頁授權 let wechat = { getCode:function(appids){ /** * 獲取微信code
【TP3.2.3】微信網頁授權--基類
重新 exec 進入 index.php sset AR 關註 fun func 非常好用的微信授權 基類:其他的微信權限類都可以繼承至該類: <?php namespace Wechat\Controller; use Think\Controller;
手把手實現微信網頁授權和微信支付,附源代碼(VUE and thinkPHP)
nec ble 名單 ret 一次 hash 掃一掃 網頁 ada wechat github 手把手實現微信網頁授權和微信支付,附源代碼(VUE and thinkPHP) 概述 公眾號開發是痛苦的,痛苦在好多問題開發者文檔是沒有提到的,是需要你猜的. 在開發過程中翻
.netMVC企業微信網頁授權+註冊全局過濾器
glob for init cgi http 一個 使用 QQ == 微信網頁授權 達到效果:企業應用只能在微信中查看,在瀏覽器中打開企業頁面,顯示無權限! 原理,用session記錄用戶,如果用戶已經通過微信授權,記錄@Session["UserId"],如果用戶
解決微信網頁授權一個回調域名多個業務使用
ces 公眾號授權 存在 方案 安全問題 TP 公眾 處理 source 前言 我們都知道微信的網頁授權回調域名只能設置一個,但是多個業務使用同一個微信公眾號授權信息的話,就需要使用者內部進行處理了,下面給出我使用的一種簡陋的解決方案。 方法 正常流程 1: 第一步:用戶同
H5獲取微信網頁授權
esp lin storage {} cti 調用接口 set auth nav //判斷是否微信瀏覽器 isWeiXin: function(){ let ua = window.navigator.userAgent.toLowerCase(); retur
微信網頁授權報code been used, hints: [ req_id: XYv1Ha07042046 ]
web 獲取 UNC color 微信網頁授權 oauth image 授權 use 先貼上代碼: public function index() { $code = input(‘get.code‘); $tool = n
VueJs單頁應用實現微信網頁授權及微信分享功能示例
在實際開發中,無論是做PC端、WebApp端還是微信公眾號等型別的專案的時候,或多或少都會涉及到微信相關的開發,最近公司專案要求實現微信網頁授權,並獲取微信使用者基本資訊的功能及微信分享的功能,現在總算完成了,但開發過程中遇到好幾個坑。廢話不多說了,開始正題。 描述點 微信相關開發知識
微信網頁授權——獲取code、access_token、openid,及跨域問題解決
首先在微信開發文件中有提到微信網頁授權的操作步驟: 第一步:使用者同意授權,獲取code 在確保微信公眾賬號擁有授權作用域(scope引數)的許可權的前提下(服務號獲得高階介面後,預設擁有scope引數中的snsapi_base和snsapi_userinfo),引導關注者開啟如下頁面:
微信網頁授權獲取code
<script> (function(){ var code = GetQueryString('code'); if(code){ alert(code) return false; }else{ shouquan(); } function shouquan(){ var redi
微信網頁授權失敗原因總結
1.專案中網頁授權回撥地址與微信公眾號設定的回撥地址不一樣 2.如果公眾號為服務號,沒有把MP_verify_zoOZRR6Jqi5eQA1n.txt貼上進專案裡 3.如果公眾號為服務號,專案必須要用域名訪問地址 4.如果公眾號為測試號,也不可以用ip地址做專案訪問地址,因為用ip地址訪問的話
PHP 微信網頁授權獲取使用者資訊
class WxController extends Controller { //put your code here /** * 微信授權相關介面
微信網頁授權access_token 與 微信基礎支援的access_token
在此總結一下網頁授權access_token 與 微信基礎支援的access_token 的區別。 1. 網頁授權access_token 微信開放平臺的使用者掃碼登陸網站, 微信公眾號的H5頁面獲取使用者資訊, 微信小程式中的access_token均
普通js使用ajax,微信公眾號授權(微信網頁授權)
微信授權的整個流程: 引導使用者進入授權頁面同意授權,獲取code 通過code換取網頁授權access_token(與基礎支援中的access_token不同) 如果需要,開發者可以重新整理網頁授權access_token,避免過期 通過網頁授權access_tok
vue腳手架,微信公眾號授權(微信網頁授權)
如果使用者在微信客戶端中訪問第三方網頁,公眾號可以通過微信網頁授權機制,來獲取使用者基本資訊,進而實現業務邏輯。 首先我做了一個H5小專案,然後申請公眾號,然後在【自定義選單】中輸入想填寫的,公眾號選單名稱,以及頁面地址: 然後,我們在我們的前端頁面寫呼叫伺服器介面,得到授權。當然
微信網頁授權中遇到的兩個小問題解決
在用微信公眾號測試賬號測試時遇到兩個問題: 1、Scope 引數錯誤或沒有 Scope 許可權 2、解決1後,遇到 redirect_uri 引數錯誤 問題1是因為測試賬號在許可權表中需要設定訪問“授權回撥頁面域名”,如果沒設定的話就會返回“Scope