关于小程序:小程序微信登录后端使用SpringBoot

1次阅读

共计 3870 个字符,预计需要花费 10 分钟才能阅读完成。

前言

官网给了这么一张图:

原文:https://developers.weixin.qq.com/miniprogram/dev/framework/op…

微信登录和一般登录

一般登录的过程是:

  1. 用户提交 username 和 password
  2. 后端查数据库,username 和 password 是否正确
  3. 如果正确,设置用户登录状态,生成 token,返回 token

微信登录的过程:

  1. 用户提交微信生成的长期 code
  2. 后端问一下微信服务器:这 code 是谁啊?微信会返回用户的 openid
  3. 后端查数据库,这 openid 的用户注册了吗?
  4. 如果注册了,设置用户登录状态,生成 token,返回 token

这么一比不难发现,微信登录只不过是把 提交明码 验证明码 的过程,变成了 查问用户身份 验证用户身份 的过程。
至于前面怎么生成 token,怎么返回,怎么设置生效工夫,就和以前明码验证是截然不同的,本文不再赘述。

操作

一、前端:wx.login 获取长期 code

数据流:用户的小程序 -> 微信服务器
官网接口文档:https://developers.weixin.qq.com/miniprogram/dev/api/open-api…

    /**
     * 生命周期函数 -- 监听页面加载
     */
    onLoad() {wx.login().then((res) => {console.log(res);
        })
    },

二、后端:起个我的项目

这一步的作用是测试前后端连通,临时不进行逻辑解决。

@RestController
@RequestMapping("wxLogin")
public class WxLoginController {@PostMapping()
    @CrossOrigin("*")
    public String Login(@RequestBody String code) {System.out.println(code);
        return "success";
    }
}

三、前端:拿着 code 申请后端的登录接口

数据流:用户的小程序 -> 开发者服务器

    /**
     * 生命周期函数 -- 监听页面加载
     */
    onLoad() {
    // 向微信服务器获取 code
        wx.login().then((res) => {
        // 拿着 code 向开发者服务器登录
            wxLogin(res.code).then((res_1) => {console.log(res_1.data);
            })
        })
    },

此处 WxLogin 办法是本人写的申请办法,本人实现即可,给出一个参考:

/**
 * 登录
 * @param username 用户名
 * @param password 明码
 */
async function wxLogin(code: string) {
    const res = await httpPost({
        url: '/wxLogin',
        header: {'content-type': 'application/json' // 默认值},
        data: {code: code}
    })
    return res;
}

// 后端地址
const baseUrl="http://localhost:8080"

/**
 * Post 形式的 HTTP 申请
 * @param requestOptions
 */
function httpPost(requestOptions: WechatMiniprogram.RequestOption) {wx.showLoading({ title: '加载中',})
  requestOptions.url = baseUrl + requestOptions.url
  requestOptions.header = {
    ...requestOptions.header,
    // "Authorization": getToken()}
  return new Promise((resolve, reject) => {
    wx.request({
      ...requestOptions,
      method: "POST",
      success(res: any) {wx.hideLoading()
        resolve(res)
      },
      fail(error) {wx.hideLoading()
        reject(error)
      }
    })
  })
}

运行后果——后端:打印了 code

前端:收到了胜利信息

四、获取 appId 和 Secret

五、后端:Apache Httpclient 和 Fast JSON

maven 依赖:

// pom.xml
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
</dependency>

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.33</version>
</dependency>

// 更新
mvn install

六、后端:拿着 code 向小程序服务器索要 token

数据流:开发者服务器 -> 微信服务器
官网接口文档:https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/u…

    // appid 和 secret
    private String appId = "你的 appid";
    private String secret = "你的 secret";
    // 这俩变量实际上应该存数据库,为了不便演示,写成变量
    private String sessionKey = "";
    private String openid = "";

    @PostMapping()
    @CrossOrigin("*")
    public String Login(@RequestBody String code) {
        // 创立 httpClient 对象
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 拼接 URL
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId +
                "&secret=" + secret +
                "&js_code=" + code.toString() +
                "&grant_type=authorization_code";
        // GET 申请对象
        HttpGet httpPost = new HttpGet(url);
        // 设置 http 的申请头,发送 json 字符串,编码 UTF-8
        httpPost.setHeader("Content-Type", "application/json;charset=utf8");
        // 响应模型
        CloseableHttpResponse response = null;
        try {// 由客户端执行(发送)Post 申请
            response = httpClient.execute(httpPost);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            // 响应实体转换为 JSON
            JSONObject jsonObject = JSONObject.parseObject(EntityUtils.toString(responseEntity));
            // 存值,仅供演示,理论应该存数据库
            sessionKey = jsonObject.getString("session_key");
            openid = jsonObject.getString("openid");
            // 生成 token,仅供演示,理论也应该存数据库,到这就和微信服务器没什么关系了,就是一般登录的流程
            String token = "Token";
            // 返回 token
            return token;
        } catch (Exception e) {e.printStackTrace();
        } finally {
            try {
                // 开释资源
                if (httpClient != null) {httpClient.close();
                }
                if (response != null) {response.close();
                }
            } catch (Exception e) {e.printStackTrace();
            }
        }

        return "";
    }

简略来说就是:

  1. 拼接 URL,发动申请
  2. 收到响应,解析响应,取出 session_key 和 openid
  3. 查数据库,找到用户信息,设置用户登录状态,返回 token(这步和微信没关系,就是一般登录,微信验证的过程代替了验证用户名明码的过程)

思考到每个人的数据库不同,ORM 层不同,第三步查数据库没有在代码中给出,而是简略的用几个变量示意。

Java 发动 HTTP 申请的代码有点长,能够形象进去,写成一个办法。

七、前端:收到 token,存 token

    /**
     * 生命周期函数 -- 监听页面加载
     */
    onLoad() {wx.login().then((res) => {wxLogin(res.code).then((res1) => {wx.setStorageSync('token', res1.data);
            })
        })
    },

当前就能够随时取 token 了,每次申请时带上 token 即可:

    wx.getStorageSync('token')

八、前面的操作就和一般登录一样了

总结

如果做过公众号的微信登录,小程序微信登录也差不多,而且更简略。
另外,解决登录的这些办法,文中为了不便展现就写在一起了,理论应该写成 MVC 拆散。

本文只公布于 segmentfault,禁止转载,如在其余平台看到请举报。

正文完
 0