nodejs实现微信授权登录

8061bb4abbdfd3a4d43d05c7ec04118e22f.jpg首先在nodejs里的config下创建一个wechat.js文件,里面配置好appid和appSecret。

let config = exports;

config.production = {
    appId: 'wxc464e493a4e946b6',
    appSecret: 'ab86e8264ed8c8a91df958a98a7928b4',

    //     appId: 'wxe27bcb44cb1e4753',
    //     appSecret: '920841d36776734b772f778cfa8c8b77',
};

config.testing = Object.assign({}, config.production);
config.development = Object.assign({}, config.production);

config.qa = Object.assign({}, config.testing, {});

config.nc = Object.assign({}, config.production, {});

config.sjhl = Object.assign({}, config.production, {});

config.gm = Object.assign({}, config.production, {});

然后在libs下创建wechat.js文件,a0e7a400dbec9258558c109e6bc970866df.jpg

里面的代码为

var fs = require('fs');
var OAuth = require('wechat-oauth');

class Wechat {
    //拿到配置文件里的appid和appSecret
    constructor(appId, appSecret) {
        this.appId = appId;
        this.appSecret = appSecret;
        this.client = new OAuth(this.appId, this.appSecret, this.getToken, this.setToken);
    }
    //从缓存中获取用户的assets token
    getToken(openid, callback) {
        let file = `runtime/access_token_${openid}.txt`;
        if (!fs.existsSync(file)) {
            return callback(null);
        }
        fs.readFile(file, 'utf8', function (err, txt) {
            if (err) {
                console.log('[wechat] get token err', err);
                return callback(err);
            }
            callback(null, JSON.parse(txt));
        });
    }
    //如果没获取到token就把token设置到缓存中
    setToken(openid, token, callback) {
        let file = `runtime/access_token_${openid}.txt`;
        fs.writeFile(file, JSON.stringify(token), callback);
    }
    //传入url让用户点击授权
    getAuthorizeURL(url) {
        let redirectUrl = this.client.getAuthorizeURL(url, 'qiongtao.li', 'snsapi_userinfo');
        return redirectUrl;
    }
    //获取用户的accessToken
    async getAccessToken(code) {
        return new Promise((resolve, reject) => {
            this.client.getAccessToken(code, (err, rst) => {
                if (err) {
                    console.log('[wechat] get access token err', err);
                    resolve();
                }
                console.log('[wechat] access token:', rst.data);
                resolve(rst.data);
            })
        })
    }
    //通过openid获取到用户信息
    async getUser(openid) {
        return new Promise((resolve, reject) => {
            this.client.getUser(openid, (err, rst) => {
                if (err) {
                    console.log('[wechat] get user info err', err);
                    resolve();
                }
                console.log('[wechat] userinfo:', rst);
                resolve(rst);
            })
        })
    }

}

module.exports = Wechat

最后在toutes里写action,代码为

const Wechat = require('../../libs/Wechat');
const Trans = require('../../libs/database/Mysql');
const Model = require('../../libs/Model');
const RecordLog = require('../../libs/Log');
const Request = require('../../libs/Request');
const redis = require('../../libs/Redis');

const wechat = new Wechat(_.config.wechat.appId, _.config.wechat.appSecret);

module.exports = {
    '/npi/wechat/login': {
        get: async (ctx, next) => {
            let echostr = ctx.query.echostr || '';
            let code = ctx.query.code || '';

            if (echostr != '') { //证明你是开发者
                return echostr;
            }
            //授权认证
            if (code == '') {
                let domain = ctx.protocol + '://' + ctx.host; //
                let url = wechat.getAuthorizeURL(domain + ctx.url);
                ctx.set('Referrer', ctx.headers['Referrer'] || `${domain}/npi/test/succ`)
                ctx.redirect('back', url);
                return '';
            }
            //获得userInfo
            let rst = await wechat.getAccessToken(code);
            let userInfo = await wechat.getUser(rst.openid);

            console.log('111111111111111111111111111', userInfo);

            //开始判断登录或者注册

            let openid = userInfo.data.openid;
            let gender = '';

            if (userInfo.data.sex == '1') {
                gender = 'MAN';
            } else {
                gender = 'WOMEN';
            }

            let row = await Model.tblGyUserSocial().where('openid', openid).where('status', 'ACTIVE').getOne();


            //登录
            if (row.id) {
                let user = await Model.tblGyUserInfo().where('id', row.user_id).getOne();

                let token = _.makeToken({
                    userId: user.id,
                    userType: 'PERSON',
                }, ctx);

                let str = {
                    userId: user.id,
                    userType: 'PERSON',
                };

                let JsStr = JSON.stringify(str);

                await redis.setex("gy:app:u:token:" + token, 7200, JsStr);


                return _.succ('登录成功!', {
                    token: token,
                });
            }

            //注册

            let data = {
                businessId: 1,
                datacenterId: 1,
                serverId: 1,
            };

            let uid = await new Request().getJSON(_.config.settings.getId, data);

            Trans.transBegin();

            let res = await Model.tblGyUserInfo()
                .set('status', 'ACTIVE')
                .set('update_time', new Date())
                .set('create_time', new Date())
                .set('id', uid)
                .set('nick_name', row.data.nickname)
                .set('gender', gender)
                .set('icon', row.data.headimgurl)
                .insert();

            if (res === false) {
                Trans.transRollback();
                return _.err('失败!', 711);
            }

            let res1 = await Model.tblGyUserSocial()
                .set('status', 'ACTIVE')
                .set('update_time', new Date())
                .set('create_time', new Date())
                .set('user_id', uid)
                .set('platform', uid)
                .set('openid', openid)
                .set('nick_name', row.data.nickname)
                .set('gender', gender)
                .set('province', row.data.province)
                .set('city', row.data.city)
                .set('country', row.data.country)
                .set('icon', row.data.headimgurl)
                .insert();

            if (res1 === false) {
                Trans.transRollback();
                return _.err('失败!', 711);
            }

            let token = _.makeToken({
                userId: uid,
                userType: 'PERSON',
            }, ctx);

            let str = {
                userId: uid,
                userType: 'PERSON',
            };

            let JsStr = JSON.stringify(str);

            await redis.setex("gy:app:u:token:" + token, 7200, JsStr);


            ctx.status = 301;
            ctx.redirect(_.config.settings.wechatRedirectUrl + `?token=${token}`);


            // return _.succ(userInfo);
        }
    },
}

 

转载于:https://my.oschina.net/u/3491770/blog/1928796

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值