百度小程序中利用原生API获取用户openid和session_key方法以及API包装

1,535 阅读3分钟

前言

前端小白,打算边学边写学习笔记,强化理解。若有不合理之处,也请大佬们帮忙指出,非常感谢!若有幸帮到他人,大家有缘,也非常开心~
关于本文内容,是在开发百度小程序中的用户登录系统时遇到的。作为初学者,有必要总结一下。

在开始正文之前,先了解一下什么是openid和session_key?
openid:用户唯一标识。百度注册用户在访问小程序时,会产生一个用户唯一的OpenID(针对该小程序)。用户openid的生成原理是,用户的百度账号再加上开发者的小程序client_id经过某种加密算法得到的。
session_key:与服务器的会话密钥。

1、利用原生API获取用户的openid和session_key

利用原生API获取用户的openid和session_key本身不难,只要找到百度小程序开发文档里的相关内容就成功一大半了。有点前端基础的同学应该都能看懂文档中的内容,并参照内容里给的案例进行开发,得到自己想要的opened和session_key。
文档地址:smartprogram.baidu.com/docs/develo…

示例代码

在js文件中:

Page({
    data: {
        sessionKey: ''
    },
    getSessionKey() {
        swan.login({
            success: res => {
                swan.request({
                    url: 'https://spapi.baidu.com/oauth/jscode2sessionkey',
                    method: 'POST',
                    header: {
                        'content-type': 'application/x-www-form-urlencoded'
                    },
                    data: {
                        // swan.login()返回的 code
                        code: res.code,
                        client_id: 'xxxxxxxxxxxxxxxxxx',
                        sk: 'xxxxxxxxxxxxxxxxxxxxxxx'
                    },
                    success: res => {
                        if (res.statusCode === 200) {
                            this.setData({
                                sessionKey: res.data.session_key || ''
                            });
                        }
                    }
                });
            }
        });
    }
});   

在 swan 文件中

<view class="intro">
    <button type="primary" bind:tap="getSessionKey">获取 session key</button>
</view>
<view class="container" s-if="{{sessionKey}}">
    <view>session key 值为:</view>
    {{sessionKey}}
</view>

res.data 的值为

# curl -d "code=xxx&client_id=xxx&sk=xxx"
https://spapi.baidu.com/oauth/jscode2sessionkey
{
    "openid": "ABCDEFG123",
    "session_key": "xxxxxx"  
}

注意点

上文示例代码的js文件中,swan.request()方法里data用到的三个数据。其中code必须是调用swan.login()方法success后返回的res.code,而client_id和sk必须分别是小程序自己的AppKey和AppSecret,否则返回不到正确的openid。

2、包装用于获得openid和session_key的api接口https://spapi.baidu.com/oauth/jscode2sessionkey

为什么要包装该接口?

  • 在上文示例代码中,我们可以看到,使用该接口需要用到小程序的AppKey和AppSecret,而AppSecret是一个非常重要的字段,使用该密码可以调用小程序的所有后台接口。所以不能把该字段放到小程序的前端代码中,因为百度手机客户端容易被反编译并轻松获得Appsecret,造成重大安全威胁。因此我们需要把Appsecret保存到后台服务器中,通过服务器使用Appsecret获取openid和session_key。
    这个说明为了安全性着想。我们不能在前端通过上文的原生接口读取用户的openid。必须把它们放在后端处理,然后通过接口的形式返回给前端。

如何做?

我用的是node.js写的后端。使用express框架,以及request模块来发起url请求

var express = require('express');
var app = express();
var request = require('request')
var URL = require('url');
app.use('/Users/xxxxxxx', express.static('/Users/xxxxxxx'));

app.get('/', function (req, res) {
   res.send('hello world');
})

app.get('/swanapp_jscode2session', function (req, res) {
    var client_id = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx';   // 换成自己的AppKey
    var sk = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx';   // 换成自己的AppSecret
    var params = URL.parse(req.url, true).query;;
    var url = 'https://spapi.baidu.com/oauth/jscode2sessionkey?code='+params.code+'&client_id='+client_id+'&sk='+sk;
    request(url, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            console.log(body) 
        }
        res.send(body);
    })
})

var server = app.listen(8081,function () {
var host = server.address().address
var port = server.address().port
console.log("应用实例,访问地址为 http://www.localhost.com:%s")
})

前端读取getopenid接口

Page({
    data: {
        sessionKey: ''
    },
    getSessionKey() {
        swan.login({
            success: res => {
                if(!!res.code){
                    swan.request({
                        url: 'http://www.localhost.com:8081/swanapp_jscode2session?code='+res.code,
                        method: 'GET',
                        header: {
                            'content-type': 'application/x-www-form-urlencoded'
                        },
                        success: res => {
                            console.log(res)
                            if (res.statusCode === 200) {
                                this.setData({
                                    openid: res.data.openid,
                                    sessionKey: res.data.session_key || ''
                                });
                            }                   
                        }
                    });
                }
            }
        });
    }
});

这样就能安全读取用户的openid和session_key了。
记住不要把自己小程序的appkey和appsecret放在前端代码中。