微信小程序——授权登录

登录流程时序

微信小程序——授权登录_第1张图片
说明:

  • 调用 wx.login()获取临时登录凭证code ,并回传到开发者服务器。
  • 调用 auth.code2Session 接口,换取用户唯一标识OpenID和会话密钥session_key
  • 之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。

注意:

  • 会话密钥 session_key 是对用户数据进行加密签名的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。

  • 临时登录凭证 code 只能使用一次。

具体实现

1、获取登录凭证code

   login() {
    wx.login({
      success(res) {
        if (res.code) {
          //发起网络请求
          wx.request({
            url: 'http://127.0.0.1:18080/wx/login',
            method: 'POST',
            header: {'content-type': 'application/x-www-form-urlencoded'},
            data: {
              code: res.code
            },
            success(res) {
              if (res.data.status == 200) {
                let ticket = res.data.ticket;
                // 保存自定义登录态至客户端
                wx.setStorage({
                  key: 'LOGIN',
                  data: ticket
                })
              } else {
                // 登录失败
                wx.removeStorage({
                  key: 'LOGIN'
                })
              }
            }
          })
        } else {
          console.log('登录失败!' + res.errMsg)
        }
      }
    })
  }

2、调用 auth.code2Session 接口校验登录凭证

GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
填入对应的小程序ID、密钥、和刚刚获得的凭证code,得到响应:

{"session_key":"5tF5KuDigyB6e4m7FigHvw==",
"openid":"orWy35UBNFZyReiUYVZvtPrqht-0"}

该信息不能直接存储至客户端,需在服务端做保存(这里选择存储至redis中)。

@RestController
@RequestMapping("/wx")
public class WeixinController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public static final String APPID = "your_appid";
    public static final String SECRET = "your_secret_key";

    @PostMapping("/login")
    public Map<String, Object> wxLogin(@RequestParam("code") String code) {
        Map<String, Object> result = new HashMap<>();
        result.put("status", 200);

        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + APPID +
                "&secret=" + SECRET + "&js_code=" + code + "&grant_type=authorization_code";

        String jsonResult = restTemplate.getForObject(url, String.class);
        if (StringUtils.contains(jsonResult, "errcode")) {
            // 登陆凭证校验错误 code been used
            result.put("status", 5000);
            result.put("msg", "登陆失败");
            return result;
        }
        // 校验通过
        //
        String md5Key = DigestUtils.md5Hex(jsonResult + "HAOKE_WX_LOGIN");
        String redisKey = "WX_LOGIN_" + md5Key;
        redisTemplate.opsForValue().set(redisKey, jsonResult, Duration.ofDays(7));
        result.put("ticket", "HAOKE_" + md5Key);

        return result;
    }
}

微信小程序——授权登录_第2张图片

错误响应:
code只能被使用一次

{"errcode":40163,"errmsg":"code been used, hints: [ req_id: tCpcZfyFe-myWCca ]"}

3、保存自定义登录态至客户端
通过wx.setStorage,具体代码在前面贴了。
微信小程序——授权登录_第3张图片
4、校验是否登录

  checkSession() {
    const _this = this;
    wx.checkSession({
      success() {
        wx.showToast({
          title: '已登录',
          icon: 'success',
          duration: 2000
        })
      },
      fail() {
        wx.showToast({
          title: '登录失效',
          icon: 'none',
          duration: 2000
        })
        _this.login() // 重新登录
      }
    })
  },

6、发起业务请求时,携带客户端中的自定义登录态,去redis查询到对应的session_key和openid。

你可能感兴趣的:(微信)