掃碼登入 簡單實現
阿新 • • 發佈:2019-01-10
簡單原理是 伺服器生成唯一的 key 附帶到login 上
使用者掃描 二維碼 並且訪問伺服器 伺服器反饋登入 狀態
前端 頁面 每隔一段時間掃描 伺服器 當前的key是否掃描, 然後後續操作
程式碼:
package main import ( "fmt" "io" "math/rand" "net/http" "time" . "github.com/soekchl/myUtils" ) const file = ` <!DOCTYPE html> <html lang="zh-ch"> <head> <meta charset="UTF-8"> <title>掃碼</title> </head> <body> <br> <p>掃碼登入</p> <img id="keyImage" src="http://qr.liantu.com/api.php?text=%v" alt="My Eth Address" title="My ETH Address"> <br> <br> </body> <script> setInterval("checkLogin()","1000"); function checkLogin() { var xhr = ajaxFunction(); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status == 200) { // 解析 資料欄位 按照js的名稱來給 console.log(xhr.responseText, keyImage.src.slice(67,123)) if (+xhr.responseText === 1) { alert('登入成功') location.reload() } else { // alert('Server Error!...') } } } } xhr.open("get", "http://10.0.82.88:8080/checkLogin?key="+keyImage.src.slice(67,123), true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded','Access-Control-Allow-Origin', '*'); xhr.send(""); } function ajaxFunction() { let xmlHttp; try { // Firefox, Opera 8.0+, Safari xmlHttp = new XMLHttpRequest(); } catch (e) { try { // Internet Explorer xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { } } } return xmlHttp; } </script> </html> ` var ( keyMap = make(map[string]int) ) func HelloServer(w http.ResponseWriter, req *http.Request) { rand.Seed(time.Now().UnixNano()) r := rand.Int() keyMap[fmt.Sprint(r)] = 1 url := fmt.Sprint("http://10.0.82.88:8080/login?key=", r) Notice(url) io.WriteString(w, fmt.Sprintf(file, url)) } func main() { http.HandleFunc("/", HelloServer) http.HandleFunc("/login", login) http.HandleFunc("/checkLogin", checkLogin) Notice("Server Start!") err := http.ListenAndServe(":8080", nil) if err != nil { panic("ListenAndServe: " + err.Error()) } } func login(w http.ResponseWriter, req *http.Request) { key := req.FormValue("key") if keyMap[key] == 1 { Notice("login ok ", key) io.WriteString(w, fmt.Sprintf("<script> alert('%v 登入成功')</script>", key)) Notice(len(key)) keyMap[key] = 2 } else { Notice("login ", key) io.WriteString(w, fmt.Sprintf("<script> alert('登入失敗') </script>")) } } func checkLogin(w http.ResponseWriter, req *http.Request) { key := req.FormValue("key") if keyMap[key] == 2 { Debug("checkLogin ok ", key) io.WriteString(w, "1") // 登入成功 } else { io.WriteString(w, "0") } }
這個東東弊端是 key 隨處可見,只是用於 學習,用在商務的話 需要慎重!!!