0.前言

这次我们来研究下微信小程序登录的实现。

1.微信小程序登录流程

1.1 官方的文档[传送门]

1.2 根据官方的登录流程时序图不难看出

  • 微信小程序首先调用wx.login()从微信服务器获取code。(此code具有时效性)
  • 微信小程序小程序发送code到开发者自己的服务器。
  • 开发者自己的服务器发送从微信小程序发送来的code到微信服务器。(微信服务器通过code验证用户身份)
  • 如果微信服务器验证code成功将会返回openid session_key等信息。
  • 开发者服务器标记用户状态返回数据给微信小程序(此处发送给微信小程序的数据可以是根据openid服务器生成的cookie,可以自己设计)
  • 微信小程序发起业务请求时携带cookie

img

2. 微信小程序服务器设置

从上面的分析我们不难发现微信小程序登陆时要向开发者的服务器发送请求,微信小程序只能向设置的服务器域名发送请求。

3. 代码分析

开发者服务器除了要向微信服务器发送从微信小程序来的code信息,要需要发送AppID(小程序ID) AppSecret(小程序密钥),可通过以下方是获得。

3.1 开发者服务器端JAVA代码

GetUserMsg类中的get(String code)方法根据code向微信服务器请求登录,并返回微信服务器返回的数据。这里使用Apache HttpComponents作为HTTP客户端向微信服务器发送请求。

<dependency>
    <groupId>org.apache.httpcomponents.client5</groupId>
    <artifactId>httpclient5</artifactId>
    <version>5.0.1</version>
</dependency>
public class GetUserMsg {
    static private String appid="wx2554028d18******";
    static private String secret="f4f9rbc4494d2*********40cb2adfg7";
    public static String get(String code){
        // httpClient对象是线程安全的,可以单例使用,提升性能
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet("https://api.weixin.qq.com/sns/jscode2session?appid="+appid+"&secret="+secret+"&js_code="+code+"&grant_type=authorization_code");
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(Timeout.ofSeconds(2))
                .setConnectionRequestTimeout(Timeout.ofSeconds(2))
                .setResponseTimeout(Timeout.ofSeconds(2))
                .build();
        httpGet.setConfig(requestConfig);
        try (CloseableHttpResponse res = httpClient.execute(httpGet)) {
            if (res.getCode() == HttpStatus.SC_OK) {
                HttpEntity entity = res.getEntity();
                return EntityUtils.toString(entity);
            } else {
                System.err.println("请求失败,状态码:" + res.getCode());
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放连接资源
            httpGet.reset();
        }
        return null;
    }
}

Login类中的login()方法接受微信小程序发来的code,调用GetUserMsg.get(code)向微信服务器请求登录,返回微信服务器返回的数据。(这里只是为了实验微信的登录功能,实际使用中请不要直接返回微信服务器返回的数据)

public class Login {
    @RequestMapping("/login")
    public String login(String code){
        return GetUserMsg.get(code);
    }
}

3.2微信小程序代码

buttonClink(event){
    wx.login({
        success (res) {
            if (res.code) {
                //发起网络请求
                wx.request({
                    url: 'https://xxxxxx.com/login',
                    data: {
                        code: res.code
                    },
                    success (res) {
                        console.log(res.data)
                    }
                })
            } else {
                console.log('登录失败!' + res.errMsg)
            }
        }
    })
}

以上

文章目录