微信公众号开发系列(二) 网页授权登录

上一篇,进行了微信公众号的服务器配置,下面开始微信公众号的网页授权

通过官网的文档,可以知道网页授权大致分为几步

这里我们暂且不考虑刷新网页授权的access_token。

第一步获取code,这个code 可以看作是一个预授权码,官方说法是一个用来换取access_token的票据,下面是第一步所需要的参数

第一个appid这个就是你公众号的标识,等于你要告诉微信,用户正在登录哪个公众号;回调地址,这个就是微信返回给你code的地址,等于你告诉微信你发code到这个地址上;sope,这个看需求,只是获取openid就用snsapi_base,需要个人信息的用snsaapi_userinfo;最后带上#wechat_redirect。记住参数的顺序不要错,微信服务器会做校验

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

下面上代码

 /**
     * @description 获取回调中的code(这个可以让前端直接去请求这个url,而不是让后端做重定向)
     * @author zhou
     * @param
     * @return
     * @date 2019/6/8
     */
    @GetMapping(value = "/preAuth")
    public void preAuth(HttpServletResponse response)  {
        //拼接请求地址
        StringBuilder sb = new StringBuilder(WxOaUrlConfig.API_PRE_AUTH);
        sb.append("appid=").append(wxOfficialsAccountConfiguration.getAppid())
           .append("&").append("redirect_uri=").append(EncoderUtil
                .UrlEncode(wxOfficialsAccountConfiguration.getRedirectUrl()))
           .append("&").append("response_type=code")
                //获取用户信息
           .append("&").append("scope=snsapi_userinfo")
           .append("&").append("state=4959a8b50e8e41ad")
           .append("#wechat_redirect");
        String url = sb.toString();
        try {
            //httpUtil.doGetJson(url);
            response.sendRedirect(url);
        } catch (IOException e) {
            log.error(e.getMessage());
            throw new HttpException(HttpErrorEnum.REQUEST_ERROR);
        }
    }

 也是比较简单的按顺序拼接好url然后以https协议重定向。(也可以让前端去请求)

第二步

在微信端同意授权后,在回调地址接受code

appid介绍过了,code可以从回调请求的参数中获取,secret是公众号的密钥开发时保存在后端。

/**
     * @description 授权回调
     * @author zhou
     * @param
     * @return
     * @date 2019/6/8
     */
    @GetMapping(value = "/authCallback")
    public WebResponse authCallBack(HttpServletRequest request){
        String code = request.getParameter("code");
        //获取网页授权的accessToken
        JSONObject tokenObject = wxOfficialAccountService.getWebAccessToken(code);
        if(!tokenObject.containsKey("access_token")){
            log.error(tokenObject.getString("errmsg"));
            throw new WxErrorException(tokenObject.getInteger("errcode"),tokenObject.get("errMsg").toString());
        }
        WebResponse webResponse = wxOfficialAccountService.loginInfo(tokenObject);
        return webResponse;
    }

 /**
     * @description 获取网页授权的accessToken
     * @author zhou
     * @param code 预授权码
     * @return jsonObject
     * @date 2019/6/8
     */
    @Override
    public JSONObject getWebAccessToken(String code) {
        //拼装url
        StringBuilder sb = new StringBuilder(WxOaUrlConfig.API_WEB_ACCESS_TOKEN);
        sb.append("appid=").append(wxOfficialsAccountConfiguration.getAppid())
           .append("&").append("secret=").append(wxOfficialsAccountConfiguration.getAppsecret())
           .append("&").append("code=").append(code)
           .append("&grant_type=authorization_code");
        String url = sb.toString();
        JSONObject jsonObject = null;
        try {
            jsonObject = httpUtil.doGetJson(url);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return jsonObject;
    }

同样拼装url进行请求,这里可以获得access_token.这个就是获取个人信息的凭证,它的有效期是两小时,在有效期内可以直接调用去请求个人信息。所以在获取后可以选择保存在第三方缓存中,比如redis中

第三步获取用户信息

 /**
     * @description 登录
     * @author zhou
     * @param tokenObject 网页授权token信息
     * @return webResponse
     * @date 2019/6/9
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public WebResponse loginInfo(JSONObject tokenObject) {
        //网页授权token存入redis
        redisUtil.set(tokenObject.getString("openid"),tokenObject.getString("access_token"),
                (long) 7200);
        //拼装请求url
        StringBuilder sb = new StringBuilder(WxOaUrlConfig.API_USER_INFO);
        sb.append("access_token=").append(tokenObject.getString("access_token"))
           .append("&").append("openid=").append(tokenObject.getString("openid"))
           .append("&").append("lang=zh_CN");
        String url = sb.toString();
        OaUserVO oaUserVO = new OaUserVO();
        try {
            //获取用户信息
            JSONObject jsonResult = httpUtil.doGetJson(url);
            if(jsonResult.containsKey("errmsg")){
                //含有错误信息
                log.error(jsonResult.getString("errmsg"));
                throw new WxErrorException(jsonResult.getInteger("errcode"),
                        jsonResult.getString("errmsg"));
            }else{
                OaUser oaUser = OaUser.builder()
                        .avatar(jsonResult.getString("headimgurl"))
                        .city(jsonResult.getString("city"))
                        .country(jsonResult.getString("country"))
                        .createTime(LocalDateTime.now())
                        .deleted(false)
                        .nickName(jsonResult.getString("nickname"))
                        .openid(jsonResult.getString("openid"))
                        .province(jsonResult.getString("province"))
                        .refreshTime(LocalDateTime.now())
                        .refreshToken(tokenObject.getString("refresh_token"))
                        .sex(jsonResult.getShort("sex"))
                        .unionid(jsonResult.containsKey("unionid")?jsonResult.getString("unionid"):null)
                        .privilege(jsonResult.getString("privilege"))
                        .updateTime(LocalDateTime.now())
                        .build();
                oaUserRepository.saveAndFlush(oaUser);
                oaUserVO.setAvatar(jsonResult.getString("headimgurl"));
                oaUserVO.setNickname(jsonResult.getString("nickname"));
                oaUserVO.setOpenid(jsonResult.getString("openid"));
                oaUserVO.setUserId(oaUser.getUserId());
            }
        } catch (Exception e) {
            log.error("登录失败");
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw new WeChatOaException(WeChatOaErrorEnum.AUTH_LOGIN_ERROR);
        }
        return WebResponse.success(oaUserVO);
    }

 

同样的也是拼装成url请求数据,将请求的数据存入数据库中。这个也比较简单,归纳一下,就是按照文档,请求数据入库。

到此微信公众号网页授权结束。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值