根據微信開放文檔,在請求 code 時我們可以提供一個名為 state 的參數。該參數用於保持請求和回調的狀態,授權請求后原樣帶回給第三方。該參數可用於防止csrf攻擊(跨站請求偽造攻擊),建議第三方帶上該參數,可設置為簡單的隨機數加session進行校驗。
根據該文檔,筆者將用戶的返回地址傳遞到了 state 中,以實現登錄成功后跳轉的功能。如果返回路徑不包含或僅包含一個 Query String 參數時,代碼可以正常工作,如果有 1 個以上的參數,則第二個既之后的參數不會被返回。
為了解決該問題,筆者將返回地址進行了 Base64 轉碼。再次測試時問題依舊:微信回調時沒有對 state 參數進行編碼(url encode)造成 Query String 部分以雙等號結尾:接收參數不完整導致 URL 解碼失敗。
一個簡單易行的方案就是將這些需要編碼的字符替換成無需編碼的字符,應用以下代碼之后該問題得到解決:
public static string Encode(byte[] bytes)
{
if (bytes.IsNullOrEmpty())
{
return string.Empty;
}
var str = Convert.ToBase64String(bytes);
str = str.Replace("+", "-").Replace("/", "_");
return str;
}
public static byte[] Decode(string str)
{
if (string.IsNullOrWhiteSpace(str))
{
return new byte[0];
}
str = str.Replace("-", "+").Replace("_", "/");
var data = Convert.FromBase64String(str);
return data;
}
以上代碼將 Base64 編碼算法中用到的 “+” 和 “/” 這兩個需要參與到 URL 編碼的算法進行了替換和還原,從而規避了微信不對參數編碼的問題。