5.小程序用户的登录以及绑定

1.首先对小程序的登录流程简单讲解

小程序用户分类:

  1. 游客:只要进入小程序就默认为游客身份,就算是游客也需要获取用户唯一标识 OpenID ,存入用户表
  2. 学生:学生信息由学校导入,学生进入后可以通过学号、手机号、姓名和身份证后6位进行绑定
  3. 导师:导师信息由学校导入,导师进入后可以通过手机号、工号、姓名进行绑定

登录流程:

《微信开放文档》:

在这里插入图片描述

在这里插入图片描述


简述一下步骤:

  1. 用户第一次进入小程序,前端调用 wx.login() 获取临时登录凭证code ,将code传给后端
  2. 后端通过code请求微信接口服务获取用户的OpenID,用OpenID来创建用户存入用户表
  3. 再通过用户编号、用户类型(会员/管理员)、客户端编号来创建Token令牌并返回给前端
  4. Token令牌有过期时间,在有效期内用户可以直接进入
  5. 当过了有效期后,就会再次通过code得到OpenID(同一个微信用户OpenID是不变的),当用户表中有OpenID时,不用再次创建,直接返回该用户,创建Token令牌返回前端

2.登录流程代码

1.weixinLogin

通过code获取openid

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class AppAuthWxLoginReqVO {
    @Schema(description = "登录 code,小程序通过 wx.login 方法获得", required = true, example = "word")
    @NotEmpty(message = "登录 code 不能为空")
    private String code;
}


@Override
public AppAuthLoginRespVO weixinLogin(AppAuthWxLoginReqVO reqVO) {
  String openid;

  try{
      WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(reqVO.getCode());
      openid = sessionInfo.getOpenid();

      // 获得获得注册用户
      MemberUserDO user = userService.createUserIfAbsent(openid, getClientIP());
      Assert.notNull(user, "获取用户失败,结果为空");
      return createTokenAfterLoginSuccess(user, user.getOpenid(), LoginLogTypeEnum.LOGIN_SOCIAL);
    }catch (Exception exception){
        throw exception(AUTH_WEIXIN_CODE_ERROR);
    }
}


2.createUserIfAbsent

通过openid创建用户(如果不存在的话)

@Override
public MemberUserDO createUserIfAbsent(String openid, String registerIp) {
    // 用户已经存在
    MemberUserDO user = memberUserMapper.selectByOpenid(openid);
    if (user != null) {
        return user;
    }
    // 用户不存在,则进行创建
    return this.createUser(openid, registerIp);
}

3.createTokenAfterLoginSuccess

通过用户编号、用户类型(会员/管理员)、客户端编号来创建Token令牌

private AppAuthLoginRespVO createTokenAfterLoginSuccess(MemberUserDO user, String openid, LoginLogTypeEnum logType) {
    // 插入登陆日志
    createLoginLog(user.getId(), openid, logType, LoginResultEnum.SUCCESS);
    // 创建 Token 令牌
    OAuth2AccessTokenRespDTO accessTokenRespDTO = oauth2TokenApi.createAccessToken(new OAuth2AccessTokenCreateReqDTO()
            .setUserId(user.getId())
            .setUserType(getUserType().getValue())
            .setClientId(OAuth2ClientConstants.CLIENT_ID_DEFAULT));
    // 构建返回结果
    System.out.println(accessTokenRespDTO);
    return AuthConvert.INSTANCE.convert(accessTokenRespDTO);
}


@Data
public class OAuth2AccessTokenCreateReqDTO implements Serializable {

    /**
     * 用户编号
     */
    @NotNull(message = "用户编号不能为空")
    private Long userId;
    /**
     * 用户类型
     */
    @NotNull(message = "用户类型不能为空")
    @InEnum(value = UserTypeEnum.class, message = "用户类型必须是 {value}")
    private Integer userType;
    /**
     * 客户端编号
     */
    @NotNull(message = "客户端编号不能为空")
    private String clientId;
    /**
     * 授权范围
     */
    private List<String> scopes;

}


4.Token令牌

@Data
@Accessors(chain = true)
public class OAuth2AccessTokenRespDTO implements Serializable {

    /**
     * 访问令牌
     */
    private String accessToken;
    /**
     * 刷新令牌
     */
    private String refreshToken;
    /**
     * 用户编号
     */
    private Long userId;
    /**
     * 用户类型
     */
    private Integer userType;
    /**
     * 过期时间
     */
    private LocalDateTime expiresTime;

}

3.学生导师身份的绑定(以学生为例)

绑定的流程:

通过前端传入的学号、姓名、手机号以及身份证后6位在学生表中查询(在studentService中),如果匹配不到,则返回学生不存在;

如果存在,则根据前端传入的用户编号,完善用户信息(将游客身份改为学生,添加手机号)(在userService中)


AppUserBindVO

@Data
@NoArgsConstructor
@AllArgsConstructor
public class AppUserBindVO {

    @Schema(description = "编号", required = true, example = "1024")
    private Long userId;

    @Schema(description = "学生学号/导师工号", required = true, example = "202052116534")
    private String number;

    @Schema(description = "姓名", required = true, example = "芋艿")
    private String name;

    @Schema(description = "身份证后6位", required = true, example = "051711")
    @Length(min = 6, max = 6, message = "身份证后6位")
    private String idLastSix;

    @Schema(description = "用户手机号", required = true, example = "15601691300")
    @Length(min = 8, max = 11, message = "手机号码长度为 8-11 位")
    private String mobile;

    @Schema(description = "角色", required = true, example = "1")
    private Integer role;

}

AppUserController层接口

@PreAuthenticated是Spring Security框架提供的一个注解,它可以应用于Spring MVC控制器的方法上,用于指定在方法执行之前要进行的身份验证操作。

在用户未登录的情况下进行api测试时,需要将它注释。

    @PostMapping("/bind")
    @Operation(summary = "用户信息绑定")
//    @PreAuthenticated
    public CommonResult<Boolean> bind(@RequestBody AppUserBindVO appUserBindVO) {
        if(appUserBindVO.getRole() == 1){
            if(studentService.bindStudent(appUserBindVO)){
                userService.bind(appUserBindVO);
            }else  throw exception(STUDENT_NOT_EXISTS);
        }
        if(appUserBindVO.getRole() == 2){
            if(mentorService.bindMentor(appUserBindVO)){
                userService.bind(appUserBindVO);
            }else  throw exception(MENTOR_NOT_EXISTS);
        }
        return success(true);
    }

StudentMapper

来判断该信息是否存在学生表中
注意Mybatis Plus中 likeLeft 的用法
可以参考《MyBatisPlus中的likeLeft和likeRight》

@Mapper
public interface StudentMapper extends BaseMapperX<StudentDO> {

    default boolean bindStudent(AppUserBindVO appUserBindVO){
        String idLastSix = appUserBindVO.getIdLastSix(); // 获取 appUserBindVO 对象的后六位字符串
        return exists(new LambdaQueryWrapperX<StudentDO>()
                .eqIfPresent(StudentDO::getStudentNumber,appUserBindVO.getNumber())
                .eqIfPresent(StudentDO::getName,appUserBindVO.getName())
                .eqIfPresent(StudentDO::getMobile,appUserBindVO.getMobile())
                .likeLeft(StudentDO::getIdCard, idLastSix)
        );
    }
}

MemberUserServiceImpl

    @Override
    public void bind(AppUserBindVO appUserBindVO) {
        LambdaUpdateWrapper<MemberUserDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(MemberUserDO::getId,appUserBindVO.getUserId())
                        .set(MemberUserDO::getMobile,appUserBindVO.getMobile())
                        .set(MemberUserDO::getRole,appUserBindVO.getRole());

        memberUserMapper.update(null,updateWrapper);
    }
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在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、付费专栏及课程。

余额充值