基于openID 的微信小程序登录+手机号绑定

基于 openID 的小程序登录和手机号绑定的流程可以分为几个步骤。以下是详细的实现步骤

提前获取小程序的   AppID(小程序ID)   和  AppSecret(小程序密钥)
(登录 微信公众平台 (qq.com) ,注册小程序,复制小程序ID和小程序密钥)

   也可以创建测试号,体验小程序开发

 

1. 登录获取 openID

  1. 用户点击登录按钮,调用 wx.login() 获取 code
  2. 将 code 发送到你的服务器。
  3. 服务器调用微信接口获取 openID 和 session_key

前端小程序代码示例

// index.js
Page({
  onLogin: function () {
    wx.login({
      success: res => {
        if (res.code) {
          // 发送 code 到你的服务器
          wx.request({
            url: 'https://your-server.com/api/login', // 你的服务器地址
            method: 'POST',
            data: {
              code: res.code
            },
            success: function (response) {
              console.log(response.data);
              // 处理服务器返回的数据,保存 session
            }
          });
        } else {
          console.log('登录失败!' + res.errMsg);
        }
      }
    });
  }
});

后端服务器端代码 Java代码示例

    private final String APP_ID = "xxxx";
    private final String APP_SECRET = "xxxx";
 
    @Autowired
    private WechatUserService wechatUserService;

    @PostMapping("/login")
    public Result login(@RequestBody Map<String, String> request) {
        String code = request.get("code");
        String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                APP_ID, APP_SECRET, code);
        Map<String, Object> result = new HashMap<>();
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(url);
            try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
                String responseBody = EntityUtils.toString(response.getEntity());
                // 处理返回的openid和session_key 转换成json格式的对象
                JSONObject jsonObject= JSON.parseObject(responseBody);
                String openid=jsonObject.getString("openid");

                // 生成自定义 Token
                String token = generateToken(openid);

                //根据openid创建用户记录,或者更新用户记录
                Boolean aBoolean = wechatUserService.verityUser(openid,token);

                result.put("openid",openid);
                result.put("phoneFlag",aBoolean);//绑定手机号标识
                result.put("AuthorizationToken",token);
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.put("errorMsg","Server error");
        }
        return Result.success(result);
    }



  //根据openId唯一标识更新或创建用户
  public Boolean verityUser(String wxOpenId,String token) {
        Boolean flag = false;
        // 设置过期时间为 8 小时
        LocalDateTime expiryTime = LocalDateTime.now().plusHours(8);
        //判断当前用户是否为新用户
        LambdaQueryWrapper<WechatUser> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(WechatUser::getWxOpenId,wxOpenId);
        List<WechatUser> list = list(queryWrapper);
        if(CollUtil.isEmpty(list)){
            //如果为空
            WechatUser user = new WechatUser();
            user.setWxOpenId(wxOpenId);
            user.setExpiryTime(expiryTime);//更新过期时间
            user.setToken(token);
            save(user);
        }else{
            //不为空,判断是否绑定手机
            WechatUser user = list.get(0);
            if(StringUtils.isNotEmpty(user.getPhone())){
                flag = true;
                user.setExpiryTime(expiryTime);//更新过期时间
                user.setToken(token);
                this.updateById(user);
            }
        }
        return flag;
    }

生成token代码

如果没有依赖,可以先添加依赖

pom文件

<!-- io.jsonwebtoken 是 Java 中用于处理 JSON Web Tokens (JWT) 的库,常用的库是 jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version> <!-- 或者使用最新版本 -->
</dependency>

token生成的代码

private final String secret_key = "5646a2c23d1e26ac";

public String generateToken(String openid) {
long nowMillis = System.currentTimeMillis();
long expMillis = nowMillis + 2 * 60 * 60 * 1000; // 2小时有效期
Date exp = new Date(expMillis);
return Jwts.builder()
.setSubject(openid)
.setIssuedAt(new Date(nowMillis))
.setExpiration(exp)
.signWith(SignatureAlgorithm.HS256, secret_key)
.compact();
}

2. 绑定手机号

  1. 用户输入手机号并请求验证码。
  2. 验证码通过短信服务发送到用户手机。
  3. 用户输入验证码并提交。
  4. 服务器验证验证码并将手机号与 openID 绑定

小程序前端代码示例:

// 发送验证码
sendSms: function () {
  const phoneNumber = this.data.phoneNumber;
  wx.request({
    url: 'https://your-server.com/api/send-sms',
    method: 'POST',
    data: { phoneNumber },
    success: function (response) {
      console.log(response.data.message);
    }
  });
}


// 绑定手机号
bindPhone: function () {
  const { openid, phoneNumber, code } = this.data; // 假设这些数据已在页面中获取
  wx.request({
    url: 'https://your-server.com/api/bind-phone',
    method: 'POST',
    data: { openid, phoneNumber, code },
    success: function (response) {
      console.log(response.data.message);
    }
  });
}

后端服务器代码 Java示例

    @PostMapping("/smsCode")
    public Result<Boolean> smsCode(@RequestBody Map<String, String> request) {
        String phoneNumber = request.get("phoneNumber");
        //调用短信服务发送短信
        wechatUserService.generateAuthCode(phoneNumber);
        return Result.success();
    }

    @PostMapping("/bindPhone")
    public Result bindPhone(@RequestBody Map<String, String> request) {
        String phoneNumber = request.get("phoneNumber");
        String openid= request.get("openId");
        String code= request.get("code");//验证码
        //校验 验证码 正确,进去微信openId和手机号的绑定
        wechatUserService.bindPhone(phoneNumber,openid,code);
        return Result.success();
    }

3. 验证token有效性

  1. 小程序在需要判断登录状态的页面中,检查本地存储中是否有 openID 或 token
  2. 小程序在后续请求中携带 Token。
  3. 服务器验证 Token 的有效性,检查是否过期,并根据 Token 中的信息进行用户身份验证

前端小程序代码示例:

// app.js
App({
  onLaunch: function () {
    const openid = wx.getStorageSync('openid');
    const session_key = wx.getStorageSync('token');

    if (openid && session_key) {
      // 用户已登录,执行后续操作
      console.log('用户已登录');
    } else {
      // 用户未登录,跳转到登录页面
      wx.redirectTo({
        url: '/pages/login/login' // 登录页面路径
      });
    }
  }
});


// 服务器端验证 session_key
app.post('/api/validVerify', async (req, res) => {
  const { openid, token} = req.body;

  // 验证 session_key 的有效性
  if (!isValidSession(token)) {
    return res.status(401).json({ error: 'token expired, please login again' });
  }

  // 继续处理请求
  res.json({ message: 'Access granted' });
});

// 判断 token是否有效的函数
function isValidSession(token) {
  // TODO: 实现 token的有效性检查逻辑
  return true; // 示例,实际应根据业务逻辑进行判断
}

Java代码示例:

 @PostMapping("/validVerify")
    public Result validVerify(@RequestHeader("Authorization") String token) {
        Claims claims;
        try {
            claims = Jwts.parser()
                    .setSigningKey(secret_key)
                    .parseClaimsJws(token)
                    .getBody();
        } catch (Exception e) {
            return Result.fail("8001","Token无效的");
        }

        String openid = claims.getSubject();
        // 检查 Token 是否过期
        LocalDateTime expiryTime = wechatUserService.findExpiryTimeByOpenid(openid);
        if (expiryTime == null || LocalDateTime.now().isAfter(expiryTime)) {
            Result.fail("9001","Token已过期,重新登录");
        }

        // 用户已登录
        return Result.success();
    }

要在PHP中实现微信小程序授权获取用户信息并绑定手机号登录,可以按照以下步骤进行操作: 1. 在微信小程序端,通过`wx.login`获取到用户的临时登录凭证`code`。 2. 将获取到的`code`发送到服务器端,使用`https`接口调用`code2Session`接口,获取到`openid`和`session_key`。 3. 将`openid`和`session_key`保存至服务器端数据库或缓存中。 4. 在小程序端,使用`wx.getUserInfo`获取用户信息,包括`nickName`、`avatarUrl`等,并将用户信息传输到服务器端。 5. 在服务器端,接收到用户信息后,将用户信息保存到服务器数据库中,可以使用`openid`作为用户的唯一标识。 6. 在小程序端,点击绑定手机号的按钮,调用`wx.request`向服务器发送请求,请求获取手机号的能力。 7. 在服务器端,接收到手机号请求后,可以返回一个包含手机号获取能力的`code`给小程序端。 8. 小程序端收到`code`后,调用`wx.request`向服务器发送请求,请求获取手机号。 9. 服务器端接收到获取手机号的请求后,可以通过调用微信开放平台提供的解密能力,解密包含手机号的数据,并将解密得到的手机号与用户信息进行绑定。 10. 绑定成功后,返回相应的状态给小程序端。 总结:通过以上步骤,我们可以在PHP中实现微信小程序授权获取用户信息并绑定手机号登录的功能。在小程序端,用户使用微信授权登录后,将用户信息传输到服务器端保存,并通过绑定手机号使用户能够更便捷地登录和使用小程序。同时,在服务器端需要进行数据加密和解密的操作,确保用户的信息安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值