Java学习:小程序微信登录开发实现

2024-06-04 6342阅读

此次开发的实现是基于B站黑马课程的学习;只涉及后端的实现,前端代码不会。。 

微信官方小程序登录开发文档链接:小程序登录 | 微信开放文档|小程序登录 | 微信开放文档


前述

小程序实现微信登录,完成具体业务的实现参考下图:

Java学习:小程序微信登录开发实现 第1张

        登录的实现需要三个端口实现 :小程序、开发者服务器、微信接口服务

        在小程序端,通过wx.login()方法获取到临时登录凭证code,将code传给开发者服务器端。

        开发者服务器端通过HttpClient创建请求,传递appid、sercet、code参数,请求微信接口服务获取openid和session_key等参数。

        开发者服务器端接收到参数以后会将openid等参数与自定义登录态关联返回到微信小程序,小程序会将自定义登录态存储,在以后进行业务请求的时候都会携带自定义登录态,开发者服务器端会验证传递过来的自定义登录态是否合法,合法则返回请求业务的数据,不合法则拒绝访问。

注意:1、code只能使用一次,每次登录需要获取新的code;2、appid与sercet是小程序创建的id和密钥;3、OpenId是用户唯一标识,每个微信用户仅有一个;补充:openid是单个小程序对微信用户只有一个,换个小程序该微信用户的openid就会变,unionid是一个微信用户不在微信平台下的任何程序都只有一个

4、自定义登录态是因为小程序没有cookie,所以只能做伪Cookie来识别用户,此处采用JWT令牌来实现

小程序获取临时登录凭证code

调用wx.login(),返回的res里面存储code,此处通过通知台将code打印出来

//获取微信登录用户的授权码
    wx.login({
      success: (res) => {
        console.log(res.code)
      }
    })

开发者服务器端实现

登录的实现,返回结果应该为一个用户对象。

调用微信接口返回OpenId,通过OpenId查询用户数据库,如果能查询到,说明存在用户;查询不到就直接实现自动注册,即封装该OpenId的用户到数据库中,返回该用户对象。然后在Controller层生成jwt令牌,将该用户对象、OpenId和jwt令牌封装成返回对象,返回给小程序端。

Controller层实现

public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    JwtProperties jwtProperties;
    @PostMapping("/login")
    @ApiOperation("微信登录")
    public Result login( @RequestBody UserLoginDTO userLoginDTO ){
        log.info("微信登录,{}",userLoginDTO);
        //调用微信登录的实现
        User user = userService.wxLogin(userLoginDTO);
        //为微信用户生成jwt令牌 传入(秘钥|过期时间|用户的唯一标识)
        Map claims = new HashMap();
        claims.put(JwtClaimsConstant.USER_ID,user.getId());
        String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(),jwtProperties.getUserTtl(),claims);
        //封装返回对象
        UserLoginVO userLoginvo = UserLoginVO.builder()
                .id(user.getId())//这里会使用用户id,后面Mapper层需要将用户id返回
                .openid(user.getOpenid())
                .token(token)
                .build();
        
        return Result.success(userLoginvo);
    }
}

注意:

1、userLoginDTO对象封装的就是临时登录凭证code

2、JwtUtil工具类的createJWT需要传递三个参数,jwt创建秘钥,jwt过期时间,自定义内容(通过Map传递),此处的参数都是通过配置类自动注入

Service层实现

@Service
public class UserServiceImpl implements UserService {
    //微信登录的配置类
    @Autowired
    WeChatProperties weChatProperties;
    private static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";
    
    @Autowired
    private UserMapper userMapper;
    
    
    /*
    * 微信登录实现*/
    @Override
    public User wxLogin(UserLoginDTO userLoginDTO) {
        //调用方法得到微信接口返回的OpenId
        String openid = getOpenid(userLoginDTO.getCode());
        //判断返回的OpenId的合法性
        if(openid == null){
            //失败抛出业务异常
            throw new LoginFailedException(MessageConstant.LOGIN_FAILED);
        }
        //合法的微信用户,判断数据库中存在该openid吗?没有则是新用户,完成自动注册
        //根据openid到User表中查询数据
        User user = userMapper.selectByOpenId(openid);
        //判断user是不是新用户,即是不是为空
        if(user == null){
            //是新用户,自动注册,存储到user表中
           user = User.builder()
                    .openid(openid)
                    .createTime(LocalDateTime.now())
                    .build();
           userMapper.insert(user);
        }
        //最后将user对象返回给Controller层,实现业务相应
        return user;
    }
    /*
    * 调用微信接口获取openid
    * */
    private String getOpenid(String code){
        //向微信接口发送请求,获取openId 和session_key
        //调用HttpClientUtil工具类的方法实现
        Map claims = new HashMap();
        //参数传递
        claims.put("appid",weChatProperties.getAppid());
        claims.put("secret",weChatProperties.getSecret());
        claims.put("js_code",code);
        claims.put("grant_type","authorization_code");
        String json = HttpClientUtil.doGet(WX_LOGIN,claims);
        JSONObject jsonObject = JSON.parseObject(json);//是将Json字符串转化为相应的对象;
        return jsonObject.getString("openid");
    }
}

Mapper层实现

Mapper层就是根据openid进行简单的查询和插入操作,只不过插入操作需要将主键id返回

@Mapper
public interface UserMapper {
    
    @Select("select * from user where openid = #{openid}")
    User selectByOpenId(String openid);
    
    /*
    * 插入数据*/
    void insert(User user);
}
 
        insert into user (openid, name, phone, sex, id_number, avatar, create_time)
        values (#{openid},#{name},#{phone},#{sex},#{idNumber},#{avatar},#{createTime})
    


    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]