Spring boot实现微信登录——后端接口

Spring boot实现微信登录

注:本文来自:B站尚硅谷尚医通项目总结

一、登录流程

1、扫码后跳转流程

在这里插入图片描述

2、获取扫描人信息

在这里插入图片描述

二、流程分析

微信官方档案
https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html

总体分析

第一步:请求code(生成授权URL)

第二步:通过code获取access_token(开发回调URL)

官网总体流程分析:

1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;

2. 通过code参数加上AppIDAppSecret等,通过API换取access_token;

3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

在这里插入图片描述

1、前端获取微信登录二维码,调用后端接口,获取微信登录生成二维码需要的参数

参数是否必须说明
appid应用唯一标识
redirect_uri请使用urlEncode对链接进行处理
response_type填code
scope应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login
state用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验

返回说明

用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数

redirect_uri?code=CODE&state=STATE

2、后点击登录,调用后台微信登录回调接口方法

说明:由于在本地测试,调用微信后台的回调地址,设置重定向到本地方法

3、获取微信回调接口的code,带着code,加上appid,appsecret,去请求微信官方固定地址,获取access_token

4、通过返回access_token字符串后,获取access_token的值和openid的值(微信唯一id)

5、判断数据库是否存在微信的扫描人信息,根据openid判断

6、没有则进行注册,带上access_token,openid去请求微信固定地址,获取扫描人信息,解析用户信息,添加进数据库

7、存在openid,进行登录,返回name和token字符串

8、最后带着token信息,重定向到登录成功首页


     /**
     * 获取微信登录生成二维码需要的参数
     * @return
     */
    @ApiOperation(value = "获取微信登录生成二维码需要的参数")
    @GetMapping("/getLoginParam")
    @ResponseBody
    public Result genQrConnect(){
        try {
            String redirectUri = URLEncoder.encode(ConstantWxPropertiesUtil.WX_OPEN_REDIRECT_URL,"UTF-8");
            HashMap<String, Object> map = new HashMap<>();
            map.put("appid", ConstantWxPropertiesUtil.WX_OPEN_APP_ID);
            map.put("scope","snsapi_login");
            map.put("redirectUri",redirectUri);
            map.put("state",System.currentTimeMillis()+"");
            return Result.ok(map);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return Result.fail(ResultCodeEnum.DATA_ERROR);
        }
    }


/**
     * 微信登录回调接口方法
     * @param code
     * @param state
     * @return 返回重定向的地址
     */
    @RequestMapping("/callback")
    public String callback(String code, String state) {
        String redirectUrl = userInfoService.wxLogin(code,state);
        return "redirect:"+redirectUrl;
    }
/**
     * 微信登录
     * @param code
     * @param state
     * @return
     */
    @Override
    public String wxLogin(String code, String state) {
        //1、获取微信回调接口的code
        System.out.println("code=:"+code);
        //2、带着code,加上appid,appsecret,去请求微信官方固定地址,获取access_token
        StringBuffer baseAccessTokenUrl = new StringBuffer()
                .append("https://api.weixin.qq.com/sns/oauth2/access_token")
                .append("?appid=%s")
                .append("&secret=%s")
                .append("&code=%s")
                .append("&grant_type=authorization_code");
        String accessTokenUrl = String.format(baseAccessTokenUrl.toString(),
                ConstantWxPropertiesUtil.WX_OPEN_APP_ID,
                ConstantWxPropertiesUtil.WX_OPEN_APP_SECRET,
                code);

        try {
            //2.1、请求Url
            String accessTokenInfo = HttpClientUtils.get(accessTokenUrl, "utf-8");
            System.out.println(accessTokenInfo);
            //3、通过返回access_token字符串后,获取access_token的值和openid的值(微信唯一id)
            JSONObject jsonObject = JSONObject.parseObject(accessTokenInfo);
            String access_token = jsonObject.getString("access_token");
            String openid = jsonObject.getString("openid");
            //4、判断数据库是否存在微信的扫描人信息,根据openid判断
            UserInfo userInfo = baseMapper.selectOne(new QueryWrapper<UserInfo>().eq("openid", openid));
            if(userInfo == null){
                //4.1、没有则进行注册,带上access_token,openid去请求微信固定地址,获取扫描人信息
                String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                        "?access_token=%s" +
                        "&openid=%s";
                String userInfoUrl = String.format(baseUserInfoUrl.toString(), access_token, openid);
                String resultInfo = HttpClientUtils.get(userInfoUrl);
                JSONObject jsonUser = JSONObject.parseObject(resultInfo);
                //解析用户信息
                //用户昵称
                String nickname = jsonUser.getString("nickname");
                //用户头像
                String headimgurl = jsonUser.getString("headimgurl");
                //4.2、获取到扫描人信息,添加进数据库
                userInfo = new UserInfo();
                userInfo.setNickName(nickname);
                userInfo.setOpenid(openid);
                userInfo.setStatus(1);
                int insert = baseMapper.insert(userInfo);
            }
            //5、存在openid,进行登录,返回name和token字符串
            Map<String,String> map = new HashMap<>();
            String name = userInfo.getName();
            if(StringUtils.isEmpty(name)) {
                name = userInfo.getNickName();
            }
            if(StringUtils.isEmpty(name)) {
                name = userInfo.getPhone();
            }
            map.put("name", name);
            //6、
            //判断userInfo是否有手机号,如果手机号为空,返回openid
            //如果手机号不为空,返回openid值是空字符串
            //前端判断:如果openid不为空,绑定手机号,如果openid为空,不需要绑定手机号
            /**
             * 阿里云短信服务现在个人无法开通,手机登录未完成,则始终让openid为空,不进行手机号绑定
             */
            //TODO 手机验证
            if(StringUtils.isEmpty(userInfo.getNickName())) {
                map.put("openid", userInfo.getOpenid());
            } else {
                map.put("openid", "");
            }
            //7、使用jwt生成token字符串
            String token = JwtHelper.createToken(userInfo.getId(), name);
            map.put("token",token);
            //8、跳转到前端页面,登录成功
            String redirectUrl = ConstantWxPropertiesUtil.YYGH_BASE_URL + "/weixin/callback?token="+map.get("token")+ "&openid="+map.get("openid")+"&name="+ URLEncoder.encode(map.get("name"),"utf-8");
            return redirectUrl;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值