nodejs實現微信受權

背景
項目基於angular1.3開發
web服務器用node,提供微信受權和跨域
使用微信jssdk獲取經緯度,再利用百度地圖API獲取用戶所在城市node

待優化問題:
項目的微信受權基於老的項目,寫的有點不夠優雅;
本身開發時把受權信息存到了sessionStorage裏面,致使每次進入項目都要走一遍受權,浪費時間和影響用戶體驗;git

解決方案:
重寫受權,讓項目初始化時只請求一個接口,就能夠拿到用戶的基本信息;將獲取的用戶基本信息存在cookie裏面,並設置一個比較長的過時時間,以便用戶在某一段時間內訪問能夠不用再次受權,拿微信受權的相關代碼就貼在下面了.github

服務端用node+expressweb

路由部分

router.js
/**
 * router
 */
const express = require("express");
const router = express.Router();
const wxAuth = require("../wxAuth.js");
router.get("/auth", wxAuth.getCode, (req, res, next) => {
    // 受權調用
});
router.get("/wxAuth/getUserInfo", wxAuth.getAccessToken, wxAuth.getUserInfo, (req, res, next) => {
    let back_url = req.query.back_url;
    console.log('back_url=='+back_url);
    if (back_url.indexOf('?path=')) {
        back_url = back_url.replace('?path=','#/')
        console.log(back_url);
    }
    res.redirect(back_url);
});
module.exports = router;

受權中間件 wxAuth.js
//微信公衆號的appId和appSecret配置文件
const weixin = require("../weixin.config.js")

const request = require('request')
const appId = weixin.appID;
const appSecret = weixin.appsecret;
const Host = 'http://example.com'
exports.getCode = (req, res, next) => {
    if (req.cookies && req.cookies.openid) {
        next();
    } else {
        console.log(req)
        let back_url = escape(req.query.back_url);
        console.log(req.query.back_url)
        let redirect_url = `http://mall.yizhenjia.com/wxAuth/getUserInfo?back_url=${back_url}`;
        let url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirect_url}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect `;
        console.log(url);
        res.redirect(url);
    }
}
exports.getAccessToken = (req, res, next) => {
    console.log('====accessToken')
    // console.log(req.query)
    let code = req.query.code;
    let url = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appId}&secret=${appSecret}&code=${code}&grant_type=authorization_code `;
    request(url, (error, response, body) => {
        let result = JSON.parse(body);
        console.log(result)
        req.access_token = result.access_token;
        req.openid = result.openid;
        next();
    });
}
exports.getUserInfo = (req, res, next) => {
    console.log('====getUserInfo')
    let access_token = req.access_token;
    let openid = req.openid;
    let url = `https://api.weixin.qq.com/sns/userinfo?access_token=${access_token}&openid=${openid}&lang=zh_CN `
    request(url, (error, response, body) => {
        console.log(body)
        let result = JSON.parse(body);
        res.cookie("openid", result.openid, { maxAge: 24 * 60 * 60 * 1000, httpOnly: false });
        res.cookie("unionid", result.unionid, { maxAge: 24 * 60 * 60 * 1000, httpOnly: false });
        res.cookie("nickname", result.nickname, { maxAge: 24 * 60 * 60 * 1000, httpOnly: false });
        res.cookie("headimgurl", result.headimgurl, { maxAge: 24 * 60 * 60 * 1000, httpOnly: false });
        next();
    });
}

在angular項目啓動的時候,就判斷有沒有用戶union的cookie存在,若是不存在就去受權,並阻止視圖渲染express

獲取受權,由於微信受權的時候,會忽略angular路由的哈希值後面的內容,因此把哈希值作了轉換,在服務端的router.js裏面,又把哈希值還原,在重定向的時候寫在url裏api

//放在commonUtil服務裏面
轉換url,將路由參數傳給服務器,而後在受權結束後,在重定向的url裏獲取路由的哈希值(這裏的哈希處理更多的是爲了後面微信支付路徑的問題)
self.getAuth = function() {
    var hash = window.location.hash.replace('#/', '?path=');
    var origin = window.location.origin;
    var pathname = window.location.pathname;
    var bcakUrl = origin + pathname + hash;
    window.location.href = "/auth?back_url=" + bcakUrl;
}
 

判斷受權,沒有受權狀況下阻止默認渲染,並請求受權(在其餘框架的時候也能夠作相似處理)
 
 $rootScope.$on('$stateChangeStart', function(event) {
   if (!cookieUtil.hasCookie("unionid") || !cookieUtil.hasCookie("openid")) {
      commonUtil.getAuth();
      event.preventDefault();
     }
 });
 //cookieUtil判斷cookie是否存在,設置cookie和獲取cookie值(angular service)

受權源碼跨域

相關文章
相關標籤/搜索